<|start_filename|>Barcodes2/CodedValueCollection.cs<|end_filename|>
﻿using System.Collections.Generic;

namespace Barcodes2
{
    /// <summary>
    /// Holds the encoded values after being parsed
    /// </summary>
    public class CodedValueCollection : List<int>
    {
    }
}


<|start_filename|>Barcode Writer/DataMatrix/OutputSettings.cs<|end_filename|>
﻿
namespace Barcodes.DataMatrix
{
    public class OutputSettings
    {
        public float Resolution
        {
            get;
            set;
        }

        public int BitSize
        {
            get;
            set;
        }

        public OutputSettings()
        {
            Resolution = 72F;
            BitSize = 2;
        }

    }
}


<|start_filename|>Barcodes2/Helpers/Code128Helper.cs<|end_filename|>
﻿
namespace Barcodes2
{
    /// <summary>
    /// Code 128 helper containing Code 128 constants
    /// </summary>
    public static class Code128Helper
    {
        /// <summary>
        /// Start value for a type A code
        /// </summary>
        public const char StartVariantA = (char)153;
        /// <summary>
        /// Start value for a type B code
        /// </summary>
        public const char StartVariantB = (char)154;
        /// <summary>
        /// Start value for a type C code
        /// </summary>
        public const char StartVariantC = (char)155;

        /// <summary>
        /// Indicate following code in a Uniform Code Council code
        /// </summary>
        public const char FNC1 = (char)152;
        /// <summary>
        /// Indicate following code in a Uniform Code Council code
        /// </summary>
        public const char FNC2 = (char)147;
        /// <summary>
        /// Indicate following code in a Uniform Code Council code
        /// </summary>
        public const char FNC3 = (char)146;
        /// <summary>
        /// Indicate following code in a Uniform Code Council code
        /// </summary>
        public const char FNC4 = (char)150;

        /// <summary>
        /// Shift the code into variant A
        /// </summary>
        public const char CODEA = (char)151;
        /// <summary>
        /// Shift the code into variant B
        /// </summary>
        public const char CODEB = (char)150;
        /// <summary>
        /// Shift the code into variant C
        /// </summary>
        public const char CODEC = (char)149;

        /// <summary>
        /// Shifts the next value between A & B
        /// </summary>
        public const char SHIFT = (char)148;
    }
}


<|start_filename|>Barcodes2/GS1/GS1Builder.cs<|end_filename|>
﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Barcodes2.GS1
{
	public class GS1Builder : IEnumerable<GS1Value>
	{
		private List<GS1Value> _values;

		public char FNC1
		{
			get;
			private set;
		}

		public System.Collections.ObjectModel.ReadOnlyCollection<GS1Value> Values
		{
			get { return new System.Collections.ObjectModel.ReadOnlyCollection<GS1Value>(_values); }
		}

		public GS1Builder()
			: this(Code128Helper.FNC1)
		{ }

		public GS1Builder(char fnc1)
		{
			_values = new List<GS1Value>();
			FNC1 = fnc1;
		}

		public void Add(int ai, string value)
		{
			var g = GS1Value.Create(ai, value);
			if (g != null)
				_values.Add(g);
		}

		public void Add(int ai, int value)
		{
			var g = GS1Value.Create(ai, value);
			if (g != null)
				_values.Add(g);
		}

		public void Add(int ai, decimal value, int precision)
		{
			var g = GS1Value.Create(ai, value, precision);
			if (g != null)
				_values.Add(g);
		}

		public void Add(int ai, DateTime value)
		{
			var g = GS1Value.Create(ai, value);
			if (g != null)
				_values.Add(g);
		}

		public void Add(int ai, DateTime value, bool ignoreDay)
		{
			var g = GS1Value.Create(ai, value);
			if (g != null)
				_values.Add(g);
		}

		public void RemoveAt(int index)
		{
			_values.RemoveAt(index);
		}

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();

			foreach (var item in _values)
			{
				sb.Append(FNC1);
				sb.Append(item.ApplicationIdentifier);
				sb.Append(item.Value);
			}

			return sb.ToString();
		}

		public string ToString(char fnc1)
		{
			FNC1 = fnc1;
			return ToString();
		}

		public string ToDisplayString()
		{
			StringBuilder sb = new StringBuilder();

			foreach (var item in _values)
			{
				sb.AppendFormat("({0})", item.ApplicationIdentifier);
				sb.Append(item.Value);
			}

			return sb.ToString();
		}

		public IEnumerator<GS1Value> GetEnumerator()
		{
			return _values.GetEnumerator();
		}

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return ((IEnumerable)_values).GetEnumerator();
		}
	}
}


<|start_filename|>Barcode Writer/1D/EAN128.cs<|end_filename|>
﻿using System.Drawing;

namespace Barcodes
{
	public class EAN128 : Code128
	{
		private GS1.GS1Builder _Value;
		//public Bitmap Generate(int aiCode, string value)
		//{
		//    return Generate(aiCode, value, DefaultSettings);
		//}

		//public Bitmap Generate(int aiCode, int specifier, string value)
		//{
		//    return Generate(aiCode, specifier, value, DefaultSettings);
		//}

		//public Bitmap Generate(int aiCode, int specifier, string value, BarcodeSettings settings)
		//{
		//    return Generate(CreateEAN128(aiCode, specifier, value), settings);
		//}

		//public Bitmap Generate(int aiCode, string value, BarcodeSettings settings)
		//{
		//    return Generate(CreateEAN128(aiCode,value), settings);
		//}

		//public Bitmap Generate(Dictionary<int, string> values)
		//{
		//    return Generate(values, DefaultSettings);
		//}

		//public Bitmap Generate(Dictionary<int, string> values, BarcodeSettings settings)
		//{
		//    StringBuilder s = new StringBuilder();

		//    s.Append(Code128Helper.StartVariantB);
		//    foreach (KeyValuePair<int, string> item in values)
		//    {
		//        s.Append(CreateEAN128(item.Key, item.Value));
		//    }

		//    return Generate(s.ToString(), settings);
		//}

		public Bitmap Generate(GS1.GS1Builder value)
		{
			AiMarker = value.FNC1;
			_Value = value;
			return Generate(value.ToString());
		}

		public Bitmap Generate(GS1.GS1Builder value, BarcodeSettings settings)
		{
			AiMarker = value.FNC1;
			_Value = value;
			return Generate(value.ToString(), settings);
		}

		protected override string ParseText(string value, CodedValueCollection codes)
		{
			value = base.ParseText(value, codes);

			if (_Value != null)
			{
				value = _Value.ToDisplayString();
				_Value = null;
			}

			return value;
		}

		//public string CreateEAN128(int aiCode, string value)
		//{
		//    return string.Format("{0}£{1}£{2}", Code128Helper.FNC1, aiCode, value);
		//}

		//public string CreateEAN128(int aiCode, int specifier, string value)
		//{
		//    return string.Format("{0}£{1}{2}£{3}", Code128Helper.FNC1, aiCode, specifier, value);
		//}
	}
}


<|start_filename|>Barcode Writer/BarcodeException.cs<|end_filename|>
﻿using System;

namespace Barcodes
{
	public class BarcodeException : Exception
	{
		public BarcodeException()
		{}

		public BarcodeException(string message)
			: base(message)
		{}

		public BarcodeException(string message, Exception innerException)
			: base(message, innerException)
		{}
	}
}


<|start_filename|>Barcode Writer/DataMatrix/DataMatrixHelper.cs<|end_filename|>
﻿using System;
using System.Linq;

namespace Barcodes.Datamatrix
{
    /// <summary>
    /// Helper class for DataMatrix
    /// </summary>
    internal class DataMatrixHelper
    {
        public DataMatrixDefinition[] _Definitions;

        #region Singleton

        private static readonly DataMatrixHelper _Instance;

        /// <summary>
        /// Gets the singleton instance of the helper
        /// </summary>
        public static DataMatrixHelper Instance
        {
            get { return _Instance; }
        }

        /// <summary>
        /// Initialises the singleton
        /// </summary>
        static DataMatrixHelper()
        {
            _Instance = new DataMatrixHelper();
        }

        #endregion

        public DataMatrixHelper()
        {
            SetupDefinitions();
        }

        /// <summary>
        /// Define the allowed definitions
        /// </summary>
        private void SetupDefinitions()
        {
            _Definitions = new DataMatrixDefinition[30];

            _Definitions[0] = new DataMatrixDefinition(10, 10, 1, 3, 5);
            _Definitions[1] = new DataMatrixDefinition(12, 12, 1, 5, 7);
            _Definitions[1] = new DataMatrixDefinition(14, 14, 1, 8, 10);
            _Definitions[1] = new DataMatrixDefinition(16, 16, 1, 12, 12);
            _Definitions[1] = new DataMatrixDefinition(18, 18, 1, 18, 14);
            _Definitions[1] = new DataMatrixDefinition(20, 20, 1, 22, 18);
            _Definitions[1] = new DataMatrixDefinition(22, 22, 1, 30, 20);
            _Definitions[1] = new DataMatrixDefinition(24, 24, 1, 36, 24);
            _Definitions[1] = new DataMatrixDefinition(26, 26, 1, 44, 28);
            _Definitions[1] = new DataMatrixDefinition(32, 32, 4, 62, 36);
            _Definitions[1] = new DataMatrixDefinition(36, 36, 4, 86, 42);
            _Definitions[1] = new DataMatrixDefinition(40, 40, 4, 114, 48);
            _Definitions[1] = new DataMatrixDefinition(44, 44, 4, 144, 56);
            _Definitions[1] = new DataMatrixDefinition(48, 48, 4, 174, 68);
            _Definitions[1] = new DataMatrixDefinition(52, 52, 4, 204, 84);
            _Definitions[1] = new DataMatrixDefinition(64, 64, 16, 280, 112);
            _Definitions[1] = new DataMatrixDefinition(72, 72, 16, 368, 144);
            _Definitions[1] = new DataMatrixDefinition(80, 80, 16, 456, 192);
            _Definitions[1] = new DataMatrixDefinition(88, 88, 16, 576, 224);
            _Definitions[1] = new DataMatrixDefinition(96, 96, 16, 696, 272);
            _Definitions[1] = new DataMatrixDefinition(104, 104, 16, 816, 336);
            _Definitions[1] = new DataMatrixDefinition(120, 120, 36, 1050, 408);
            _Definitions[1] = new DataMatrixDefinition(132, 132, 36, 1304, 496);
            _Definitions[1] = new DataMatrixDefinition(144, 144, 36, 1558, 620);
            _Definitions[1] = new DataMatrixDefinition(8, 18, 1, 5, 7);
            _Definitions[1] = new DataMatrixDefinition(8, 32, 2, 10, 11);
            _Definitions[1] = new DataMatrixDefinition(12, 26, 1, 16, 14);
            _Definitions[1] = new DataMatrixDefinition(12, 36, 2, 12, 18);
            _Definitions[1] = new DataMatrixDefinition(16, 36, 2, 32, 24);
            _Definitions[1] = new DataMatrixDefinition(16, 48, 2, 49, 28);
        }

        /// <summary>
        /// Get a definition for the required data word count
        /// </summary>
        /// <param name="size">dataword count</param>
        /// <returns>DataMatrixDefintion capable of holding the specified number of words</returns>
        public DataMatrixDefinition GetDefinitionForSize(int size)
        {
            var q = (from t in _Definitions where t.DataWords >= size select t).ToArray();

            if (q.Length == 0)
                throw new ArgumentException("There is too much data to store.");

            return q[0];
        }

        /// <summary>
        /// Gets an array of column counts
        /// </summary>
        /// <returns></returns>
        public int[] GetSizes()
        {
            var q = from t in _Definitions select t.Cols;

            return q.ToArray();
        }

        /// <summary>
        /// Validates a matix size against the allowed sizes
        /// </summary>
        /// <param name="size">matix size to validate</param>
        /// <returns>true if the size is valid</returns>
        public bool ValidateSize(System.Drawing.Size size)
        {
            return _Definitions.Count(n => n.Cols == size.Width && n.Rows == size.Height) > 0;
        }
    }
}


<|start_filename|>Barcode Writer/1D/Code93.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;

namespace Barcodes
{
    public class Code93 : BarcodeBase
    {
        private const int SHIFT1 = 43;
        private const int SHIFT2 = 44;
        private const int SHIFT3 = 45;
        private const int SHIFT4 = 46;
        private const int LIMIT = 47;
        private const int TERMINATOR = 48;

        protected override void Init()
        {
            DefaultSettings.ModulePadding = 0;

            AllowedCharsPattern = new System.Text.RegularExpressions.Regex(".+");

            AddChecksum += new EventHandler<AddChecksumEventArgs>(Code93_AddChecksum);
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();

            PatternSet.Add(0, Pattern.Parse("100010100"));
            PatternSet.Add(1, Pattern.Parse("101001000"));
            PatternSet.Add(2, Pattern.Parse("101000100"));
            PatternSet.Add(3, Pattern.Parse("101000010"));
            PatternSet.Add(4, Pattern.Parse("100101000"));
            PatternSet.Add(5, Pattern.Parse("100100100"));
            PatternSet.Add(6, Pattern.Parse("100100010"));
            PatternSet.Add(7, Pattern.Parse("101010000"));
            PatternSet.Add(8, Pattern.Parse("100010010"));
            PatternSet.Add(9, Pattern.Parse("100001010"));
            PatternSet.Add(10, Pattern.Parse("110101000"));
            PatternSet.Add(11, Pattern.Parse("110100100"));
            PatternSet.Add(12, Pattern.Parse("110100010"));
            PatternSet.Add(13, Pattern.Parse("110010100"));
            PatternSet.Add(14, Pattern.Parse("110010010"));
            PatternSet.Add(15, Pattern.Parse("110001010"));
            PatternSet.Add(16, Pattern.Parse("101101000"));
            PatternSet.Add(17, Pattern.Parse("101100100"));
            PatternSet.Add(18, Pattern.Parse("101100010"));
            PatternSet.Add(19, Pattern.Parse("100110100"));
            PatternSet.Add(20, Pattern.Parse("100110010"));
            PatternSet.Add(21, Pattern.Parse("101011000"));
            PatternSet.Add(22, Pattern.Parse("101001100"));
            PatternSet.Add(23, Pattern.Parse("101000110"));
            PatternSet.Add(24, Pattern.Parse("100101100"));
            PatternSet.Add(25, Pattern.Parse("100010110"));
            PatternSet.Add(26, Pattern.Parse("110110100"));
            PatternSet.Add(27, Pattern.Parse("110110010"));
            PatternSet.Add(28, Pattern.Parse("110101100"));
            PatternSet.Add(29, Pattern.Parse("110100110"));
            PatternSet.Add(30, Pattern.Parse("110010110"));
            PatternSet.Add(31, Pattern.Parse("110011010"));
            PatternSet.Add(32, Pattern.Parse("101101100"));
            PatternSet.Add(33, Pattern.Parse("101100110"));
            PatternSet.Add(34, Pattern.Parse("100110110"));
            PatternSet.Add(35, Pattern.Parse("100111010"));
            PatternSet.Add(36, Pattern.Parse("100101110"));
            PatternSet.Add(37, Pattern.Parse("111010100"));
            PatternSet.Add(38, Pattern.Parse("111010010"));
            PatternSet.Add(39, Pattern.Parse("111001010"));
            PatternSet.Add(40, Pattern.Parse("101101110"));
            PatternSet.Add(41, Pattern.Parse("101110110"));
            PatternSet.Add(42, Pattern.Parse("110101110"));

            PatternSet.Add(SHIFT1, Pattern.Parse("100100110"));
            PatternSet.Add(SHIFT2, Pattern.Parse("111011010"));
            PatternSet.Add(SHIFT3, Pattern.Parse("111010110"));
            PatternSet.Add(SHIFT4, Pattern.Parse("100110010"));

            PatternSet.Add(LIMIT, Pattern.Parse("101011110"));
            PatternSet.Add(TERMINATOR, Pattern.Parse("1"));
        }

        private void Code93_AddChecksum(object sender, AddChecksumEventArgs e)
        {
            AddCheckDigit(e, 20);
            AddCheckDigit(e, 15);
        }

        private void AddCheckDigit(AddChecksumEventArgs e, int weight)
        {
            int total = 0;
            int w = 1;
            for (int i = e.Codes.Count - 2; i > 0; i--)
            {
                total += (w * e.Codes[i]);
                w++;
                if (w > weight)
                    w = 1;
            }

            total = total % 47;
            e.Codes.Insert(e.Codes.Count - 2, total);
        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            value = base.ParseText(value, codes);

            string tmp = null;
            foreach (char item in value.ToCharArray())
            {
                if (item == ' ')
                    codes.Add(38);
                else if (item == '$')
                    codes.Add(39);
                else if (item == '/')
                    codes.Add(40);
                else if (item == '+')
                    codes.Add(41);
                else if (item == '%')
                    codes.Add(42);

                else if (item >= '0' && item <= '9')
                    codes.Add(item - 48);
                else
                {
                    tmp = AsciiEncoder.Lookup(item);

                    switch (tmp[0])
                    {
                        case '$':
                            codes.Add(SHIFT1);
                            codes.Add(tmp[1] - 55);
                            break;
                        case '%':
                            codes.Add(SHIFT2);
                            codes.Add(tmp[1] - 55);
                            break;
                        case '/':
                            codes.Add(SHIFT3);
                            codes.Add(tmp[1] - 55);
                            break;
                        case '+':
                            codes.Add(SHIFT4);
                            codes.Add(tmp[1] - 55);
                            break;
                        default:
                            codes.Add(tmp[0]);
                            break;
                    }
                }

            }

            codes.Insert(0, LIMIT);
            codes.Add(LIMIT);
            codes.Add(TERMINATOR);

            return value;
        }

        protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
        {
            width += ((codes.Count - 1) * 9 * settings.NarrowWidth) + settings.NarrowWidth;

            return base.OnCalculateWidth(width, settings, codes);
        }
    }
}


<|start_filename|>WebControls/Mvc/BarcodeHelper.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace Barcodes.Web.Mvc
{
	/// <summary>
	/// Helper class to generate paths to the barcode image handler
	/// </summary>
	public static class BarcodeHelper
	{
		/// <summary>
		/// Draw a barcode. size is calculated automatically, margins set to 0
		/// </summary>
		/// <param name="helper"></param>
		/// <param name="data">barcode data</param>
		/// <param name="format">barcode format</param>
		public static string Barcode(this HtmlHelper helper, string data, BarcodeFormats format)
		{
			return BarcodeHelper.Barcode(helper, data, format, null);
		}

		//public static void Barcode(this HtmlHelper helper, string data, BarcodeFormats format, string imageFormat)
		//{
		//    BarcodeHelper.Barcode(helper, data, format, imageFormat, null);
		//}

		public static string Barcode(this HtmlHelper helper, string data, object options)
		{
			return Barcode(helper, data, new System.Web.Routing.RouteValueDictionary(options));
		}

		public static string Barcode(this HtmlHelper helper, string data, BarcodeFormats format, IDictionary<string, object> options)
		{
			return RequestSettings.UrlBuilder(data, format, options);
		}
	}
}


<|start_filename|>Barcodes2/Definitions/Single/Code2of5.cs<|end_filename|>
﻿using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Barcodes2.Definitions.Single
{
	public class Code2of5 : DefaultDefinition
	{
		private const int START = 10;
		private const int STOP = 11;

		protected override Regex GetRegex()
		{
			return new System.Text.RegularExpressions.Regex("^\\d+");
		}

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			PatternSet.Add(0, Pattern.Parse("nb nw nb nw wb nw wb nw nb"));
			PatternSet.Add(1, Pattern.Parse("wb nw nb nw nb nw nb nw wb"));
			PatternSet.Add(2, Pattern.Parse("nb nw wb nw nb nw nb nw wb"));
			PatternSet.Add(3, Pattern.Parse("wb nw wb nw nb nw nb nw nb"));
			PatternSet.Add(4, Pattern.Parse("nb nw nb nw wb nw nb nw wb"));
			PatternSet.Add(5, Pattern.Parse("wb nw nb nw wb nw nb nw nb"));
			PatternSet.Add(6, Pattern.Parse("nb nw wb nw wb nw nb nw nb"));
			PatternSet.Add(7, Pattern.Parse("nb nw nb nw nb nw wb nw wb"));
			PatternSet.Add(8, Pattern.Parse("wb nw nb nw nb nw wb nw nb"));
			PatternSet.Add(9, Pattern.Parse("nb nw wb nw nb nw wb nw nb"));

			PatternSet.Add(START, Pattern.Parse("wb nw wb nw nb"));
			PatternSet.Add(STOP, Pattern.Parse("wb nw nb nw wb"));
		}

		public override CodedValueCollection GetCodes(string value)
		{
			var result = new CodedValueCollection();

			for (int i = 0; i < value.Length; i++)
			{
				result.Add(int.Parse(value.Substring(i, 1)));
			}

			result.Insert(0, START);
			result.Add(STOP);

			return result;
		}

		public override int CalculateWidth(BarcodeSettings settings, CodedValueCollection codes)
		{
			var width = (codes.Count - 2) * ((7 * settings.NarrowWidth) + (2 * settings.WideWidth) + settings.ModulePadding);
			return width + (4 * settings.WideWidth) + (6 * settings.NarrowWidth);
		}

		public override string AddChecksum(string value, CodedValueCollection codes)
		{
			int total = 0;
			bool isEven = true;

			for (int i = codes.Count - 2; i < 0; i--)
			{
				total += isEven ? 3 * codes[i] : codes[i];
			}

			total = total % 10;
			total = total == 0 ? 0 : 10 - total;
			codes.Insert(codes.Count - 1, total);
			
			return value + total.ToString();
		}
	}
}


<|start_filename|>Barcode Writer/1D/Code11.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;

namespace Barcodes
{
    public class Code11 : BarcodeBase
    {
        private const int LIMIT = 's';

        protected override void Init()
        {
            AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^[\\d-]+$");

            this.AddChecksum += new EventHandler<AddChecksumEventArgs>(Code11_AddChecksum);
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();

            PatternSet.Add('0', Pattern.Parse("nb nw nb nw wb"));
            PatternSet.Add('1', Pattern.Parse("wb nw nb nw wb"));
            PatternSet.Add('2', Pattern.Parse("nb ww nb nw wb"));
            PatternSet.Add('3', Pattern.Parse("wb ww nb nw nb"));
            PatternSet.Add('4', Pattern.Parse("nb nw wb nw wb"));
            PatternSet.Add('5', Pattern.Parse("wb nw wb nw nb"));
            PatternSet.Add('6', Pattern.Parse("nb ww wb nw nb"));
            PatternSet.Add('7', Pattern.Parse("nb nw nb ww wb"));
            PatternSet.Add('8', Pattern.Parse("wb nw nb ww nb"));
            PatternSet.Add('9', Pattern.Parse("wb nw nb nw nb"));
            PatternSet.Add('-', Pattern.Parse("nb nw wb nw nb"));
            PatternSet.Add('s', Pattern.Parse("nb nw wb ww nb"));
        }

        void Code11_AddChecksum(object sender, AddChecksumEventArgs e)
        {
            e.Codes.RemoveAt(e.Codes.Count - 1);
            DoChecksumCalculation(e, 10);

            if (e.Text.Length >= 10)
                DoChecksumCalculation(e, 9);

            e.Codes.Add(LIMIT);
        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            if (!IsValidData(value))
                throw new ApplicationException();

            string tmp = string.Format("{1}{0}{1}", value, (char)LIMIT);

            foreach (char item in tmp.ToCharArray())
            {
                codes.Add(item);
            }

            return value;
        }

        protected void DoChecksumCalculation(AddChecksumEventArgs e, int factor)
        {
            int tmp = 0;
            int weight = 0;
            for (int i = 0; i < e.Text.Length; i++)
            {
                weight = ((e.Text.Length - i) % factor);
                if (weight == 0)
                    weight = factor;
                tmp += ((e.Text[i] == '-' ? 10 : int.Parse(e.Text.Substring(i, 1))) * weight);
            }

            tmp = tmp % 11;
            e.Text += tmp > 9 ? "-" : tmp.ToString();
            if (e.Codes != null)
            {
                if (e.Codes[e.Codes.Count - 1] == LIMIT)
                    e.Codes.Insert(e.Codes.Count - 1, tmp > 9 ? '-' : tmp + '0');
                else
                    e.Codes.Add(tmp > 9 ? '-' : tmp + '0');
            }
        }

        public string AddSingleCheckDigit(string value)
        {
            AddChecksumEventArgs e = new AddChecksumEventArgs(value, null);
            DoChecksumCalculation(e, 10);

            return e.Text;
        }

        public string AddDoubleCheckDigit(string value)
        {
            AddChecksumEventArgs e = new AddChecksumEventArgs(value, null);
            DoChecksumCalculation(e, 10);
            DoChecksumCalculation(e, 9);

            return e.Text;
        }

        protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
        {
            foreach (int item in codes)
            {
                width += (PatternSet[item].WideCount * settings.WideWidth) + (PatternSet[item].NarrowCount * settings.NarrowWidth);
            }

            return base.OnCalculateWidth(width, settings, codes);
        }
    }
}


<|start_filename|>Barcode Writer/1D/Codabar.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;

namespace Barcodes
{
    /// <summary>
    /// Codabar generator
    /// </summary>
    public class Codabar : BarcodeBase
    {
        public const string LIMITVALUEA = "A";
        public const string LIMITVALUEB = "B";
        public const string LIMITVALUEC = "C";
        public const string LIMITVALUED = "D";

        private const string _Extras = ":/.+abcdent*";
        
        protected override void Init()
        {
            AllowedCharsPattern = new System.Text.RegularExpressions.Regex(@"^[atbnc\*de][\d-$:/\.\+]+[atbnc\*de]$", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            value = value.ToLower();
            string tmp = value.Replace(" ", "");

            tmp = base.ParseText(tmp, codes);

            foreach (char item in tmp.ToCharArray())
            {
                codes.Add(item);
            }

            return value.Substring(1, value.Length - 2);
        }

        protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
        {
            foreach (int item in codes)
            {
                width += (PatternSet[item].NarrowCount * settings.NarrowWidth) + (PatternSet[item].WideCount * settings.WideWidth);
            }

            return base.OnCalculateWidth(width, settings, codes);
        }

        public static void AddChecksumEventHandler(object sender, AddChecksumEventArgs e)
        {
            string value = e.Text.Replace(" ", "");
            if (!System.Text.RegularExpressions.Regex.IsMatch(value, "^\\d+$"))
                throw new ArgumentException("Only numeric values can have a check digit");

            int total = 0;

            for (int i = 0; i < value.Length; i++)
            {
                if (i % 2 == 0)
                    total += int.Parse(value.Substring(i, 1));
                else
                {
                    int tmp = int.Parse(value.Substring(i, 1)) * 2;
                    total += (tmp % 9);
                }
            }

            total = total % 10;

            e.Text += total.ToString();
            e.Codes.Insert(e.Codes.Count - 1, total.ToString()[0]);
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();

            PatternSet.Add('0', Pattern.Parse("nb nw nb nw nb ww wb"));
            PatternSet.Add('1', Pattern.Parse("nb nw nb nw wb ww nb"));
            PatternSet.Add('2', Pattern.Parse("nb nw nb ww nb nw wb"));
            PatternSet.Add('3', Pattern.Parse("wb ww nb nw nb nw nb"));
            PatternSet.Add('4', Pattern.Parse("nb nw wb nw nb ww nb"));
            PatternSet.Add('5', Pattern.Parse("wb nw nb nw nb ww nb"));
            PatternSet.Add('6', Pattern.Parse("nb ww nb nw nb nw wb"));
            PatternSet.Add('7', Pattern.Parse("nb ww nb nw wb nw nb"));
            PatternSet.Add('8', Pattern.Parse("nb ww wb nw nb nw nb"));
            PatternSet.Add('9', Pattern.Parse("wb nw nb ww nb nw nb"));

            PatternSet.Add('-', Pattern.Parse("nb nw nb ww wb nw nb"));
            PatternSet.Add('$', Pattern.Parse("nb nw wb ww nb nw nb"));
            PatternSet.Add(':', Pattern.Parse("wb nw nb nw wb nw wb"));
            PatternSet.Add('/', Pattern.Parse("wb nw wb nw nb nw wb"));
            PatternSet.Add('.', Pattern.Parse("wb nw wb nw wb nw nb"));
            PatternSet.Add('+', Pattern.Parse("nb nw wb nw wb nw wb"));

            PatternSet.Add('a', Pattern.Parse("nb nw wb ww nb ww nb"));
            PatternSet.Add('b', Pattern.Parse("nb ww nb ww nb nw wb"));
            PatternSet.Add('c', Pattern.Parse("nb nw nb ww nb ww wb"));
            PatternSet.Add('d', Pattern.Parse("nb nw nb ww wb ww nb"));
            PatternSet.Add('t', Pattern.Parse("nb nw wb ww nb ww nb"));
            PatternSet.Add('n', Pattern.Parse("nb ww nb ww nb nw wb"));
            PatternSet.Add('*', Pattern.Parse("nb nw nb ww nb ww wb"));
            PatternSet.Add('e', Pattern.Parse("nb nw nb ww wb ww nb"));
        }
    }
}


<|start_filename|>Barcode Writer/Postal/RM4SCC.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;

namespace Barcodes
{
    /// <summary>
    /// Royal Mail 4-Sate Customer Code generator
    /// </summary>
    public class RM4SCC : BarcodeBase
    {
        private const int START = '(';
        private const int STOP = ')';

        public const string DEFAULTDPS1 = "9U";
        public const string DEFAULTDPS2 = "9W";
        public const string DEFAULTDPS3 = "9X";
        public const string DEFAULTDPS4 = "9Y";
        public const string DEFAULTDPS5 = "9Z";

        protected override void Init()
        {
            //DPS [1-9][ABD-HJLNP-UW-Z]
            AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^[a-z0-9]{5-7}[1-9][ABD-HJLNP-UW-Z]?$");

            AddChecksum += new EventHandler<AddChecksumEventArgs>(RM4SCC_AddChecksum);

            DefaultSettings.IsTextShown = false;
            DefaultSettings.BarHeight = 12;
            DefaultSettings.MediumHeight = 8;
            DefaultSettings.ShortHeight = 4;
        }

        void RM4SCC_AddChecksum(object sender, AddChecksumEventArgs e)
        {
            int[] values = new int[PatternSet.Count];
            PatternSet.Keys.CopyTo(values, 0);

            int rowTotal = 0, colTotal = 0, tmp;

            for(int i = 1;i < e.Codes.Count -1; i++)
            {
                int index = Array.IndexOf(values, e.Codes[i]);
                tmp = (index / 6) + 1;
                rowTotal += (tmp == 6 ? 0 : tmp);

                tmp = (index % 6) + 1;
                colTotal += (tmp == 6 ? 0 : tmp);
            }

            rowTotal = rowTotal % 6;
            rowTotal = rowTotal == 0 ? 6 : rowTotal - 1;

            colTotal = colTotal % 6;
            colTotal = colTotal == 0 ? 5 : colTotal - 1;

            e.Codes.Insert(e.Codes.Count - 1, values[(rowTotal * 6) + colTotal]);
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();

            PatternSet.Add('0', Pattern.Parse("ttff"));
            PatternSet.Add('1', Pattern.Parse("tdaf"));
            PatternSet.Add('2', Pattern.Parse("tdfa"));
            PatternSet.Add('3', Pattern.Parse("dtaf"));
            PatternSet.Add('4', Pattern.Parse("dtfa"));
            PatternSet.Add('5', Pattern.Parse("ddaa"));
            PatternSet.Add('6', Pattern.Parse("tadf"));
            PatternSet.Add('7', Pattern.Parse("tftf"));
            PatternSet.Add('8', Pattern.Parse("tfda"));
            PatternSet.Add('9', Pattern.Parse("datf"));

            PatternSet.Add('A', Pattern.Parse("dada"));
            PatternSet.Add('B', Pattern.Parse("dfta"));
            PatternSet.Add('C', Pattern.Parse("tafd"));
            PatternSet.Add('D', Pattern.Parse("tfad"));
            PatternSet.Add('E', Pattern.Parse("tfft"));
            PatternSet.Add('F', Pattern.Parse("daad"));
            PatternSet.Add('G', Pattern.Parse("daft"));
            PatternSet.Add('H', Pattern.Parse("dfat"));
            PatternSet.Add('I', Pattern.Parse("atdf"));
            PatternSet.Add('J', Pattern.Parse("adtf"));
            PatternSet.Add('K', Pattern.Parse("adda"));
            PatternSet.Add('L', Pattern.Parse("fttf"));
            PatternSet.Add('M', Pattern.Parse("ftda"));
            PatternSet.Add('N', Pattern.Parse("fdta"));
            PatternSet.Add('O', Pattern.Parse("atfd"));
            PatternSet.Add('P', Pattern.Parse("adad"));
            PatternSet.Add('Q', Pattern.Parse("adft"));
            PatternSet.Add('R', Pattern.Parse("ftad"));
            PatternSet.Add('S', Pattern.Parse("ftft"));
            PatternSet.Add('T', Pattern.Parse("fdat"));
            PatternSet.Add('U', Pattern.Parse("aadd"));
            PatternSet.Add('V', Pattern.Parse("aftd"));
            PatternSet.Add('W', Pattern.Parse("afdt"));
            PatternSet.Add('X', Pattern.Parse("fatd"));
            PatternSet.Add('Y', Pattern.Parse("fadt"));
            PatternSet.Add('Z', Pattern.Parse("fftt"));

            PatternSet.Add(START, Pattern.Parse("a"));
            PatternSet.Add(STOP, Pattern.Parse("f"));

        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            value = base.ParseText(value, codes);

            foreach (var item in value.ToCharArray())
            {
                codes.Add(item);
            }

            codes.Insert(0, START);
            codes.Add(STOP);

            return value;
        }
    }
}


<|start_filename|>Barcodes2/DataMatrix/MemoryStreamExtensions.cs<|end_filename|>
﻿using System.IO;

namespace Barcodes2.DataMatrix
{
	internal static class MemoryStreamExtensions
	{
		public static void WriteInt(this MemoryStream stream, int value)
		{
			stream.WriteByte((byte)value);
		}
	}
}


<|start_filename|>Barcode Writer/1D/UPC.cs<|end_filename|>
﻿using System;

namespace Barcodes
{
    /// <summary>
    /// Universal Product Code (UPC) 12 digit code
    /// Also known as UPC-A
    /// </summary>
    public class UPC : EAN
    {
        private readonly int[] _DigitGrouping;

         protected override int[] DigitGrouping
        {
            get { return _DigitGrouping; }
        }

        public UPC()
            : base()
        {
            _DigitGrouping = new int[] { 0, 6, 6 };
        }

        protected override void Init()
        {
            base.Init();
            AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^\\d{11,12}$");

            AddChecksum += new EventHandler<AddChecksumEventArgs>(UPC_AddChecksum);
        }

        void UPC_AddChecksum(object sender, AddChecksumEventArgs e)
        {
            if (e.Codes.Count == 12)
                return;

            int total = 0;
            for (int i = 0; i < e.Codes.Count; i++)
            {
                if (i % 2 == 1)
                    total += (e.Codes[i] % 10);
                else
                    total += 3 * (e.Codes[i] % 10);
            }

            total = total % 10;
            e.Codes.Add(total == 0 ? 20 : 30 - total);
            e.Text += (total == 0 ? 0 : 10 - total).ToString();

        }

        protected override void CalculateParity(CodedValueCollection codes)
        {
            codes.Insert(0, 0);
            base.CalculateParity(codes);
        }

        public static string FromUPCE(string value)
        {
            return UPCE.ToUpcA(value);
        }

        public static string ToUPCE(string value)
        {
            return UPCE.FromUpcA(value);
        }
    }
}


<|start_filename|>Barcodes2/Generator.cs<|end_filename|>
﻿
namespace Barcodes2
{
	public class Generator
	{
		private readonly Services.IRenderer _renderer;
		private readonly Services.DefinitionFactory _definitions;

		public BarcodeSettings Settings
		{
			get;
			set;
		}

		public string RendererName
		{
			get { return _renderer.Name; }
		}

		public Generator()
			: this(null)
		{ }

		public Generator(BarcodeSettings settings)
			: this(Services.Locator.Get<Services.BitmapRenderer>(), Services.Locator.Get<Services.DefinitionFactory>(), settings)
		{ }

		public Generator(Services.IRenderer renderer, Services.DefinitionFactory definitions, BarcodeSettings settings)
		{
			_renderer = renderer;
			_definitions = definitions;
			Settings = settings ?? new BarcodeSettings();
		}

		public object Create(string value, BarcodeFormats format)
		{
			return Create(value, _definitions.GetDefinition(format));
		}

		public object Create(string value, Definitions.IDefinition definition)
		{
			_renderer.Settings = Settings.Copy();
			definition.TransformSettings(_renderer.Settings);

			if (!definition.IsDataValid(value))
				throw new BarcodeException();

			var codes = definition.GetCodes(value);
			var dt = definition.GetDisplayText(value);

			if (definition.IsChecksumRequired || _renderer.Settings.IsChecksumCalculated)
				dt = definition.AddChecksum(dt, codes);

			_renderer.Definition = definition;

			return _renderer.Render(codes, dt);
		}
	}
}


<|start_filename|>Barcodes2/Definitions/Single/Code3of9.cs<|end_filename|>
﻿using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Barcodes2.Definitions.Single
{
	public class Code3of9 : DefaultDefinition
	{
		protected override Regex GetRegex()
		{
			return new Regex("^[A-Z0-9-\\. \\$/+%]+$", RegexOptions.IgnoreCase);
		}

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			PatternSet.Add('0', Pattern.Parse("nb nw nb ww wb nw wb nw nb"));
			PatternSet.Add('1', Pattern.Parse("wb nw nb ww nb nw nb nw wb"));
			PatternSet.Add('2', Pattern.Parse("nb nw wb ww nb nw nb nw wb"));
			PatternSet.Add('3', Pattern.Parse("wb nw wb ww nb nw nb nw nb"));
			PatternSet.Add('4', Pattern.Parse("nb nw nb ww wb nw nb nw wb"));
			PatternSet.Add('5', Pattern.Parse("wb nw nb ww wb nw nb nw nb"));
			PatternSet.Add('6', Pattern.Parse("nb nw wb ww wb nw nb nw nb"));
			PatternSet.Add('7', Pattern.Parse("nb nw nb ww nb nw wb nw wb"));
			PatternSet.Add('8', Pattern.Parse("wb nw nb ww nb nw wb nw nb"));
			PatternSet.Add('9', Pattern.Parse("nb nw wb ww nb nw wb nw nb"));
			PatternSet.Add('A', Pattern.Parse("wb nw nb nw nb ww nb nw wb"));
			PatternSet.Add('B', Pattern.Parse("nb nw wb nw nb ww nb nw wb"));
			PatternSet.Add('C', Pattern.Parse("wb nw wb nw nb ww nb nw nb"));
			PatternSet.Add('D', Pattern.Parse("nb nw nb nw wb ww nb nw wb"));
			PatternSet.Add('E', Pattern.Parse("wb nw nb nw wb ww nb nw nb"));
			PatternSet.Add('F', Pattern.Parse("nb nw wb nw wb ww nb nw nb"));
			PatternSet.Add('G', Pattern.Parse("nb nw nb nw nb ww wb nw wb"));
			PatternSet.Add('H', Pattern.Parse("wb nw nb nw nb ww wb nw nb"));
			PatternSet.Add('I', Pattern.Parse("nb nw wb nw nb ww wb nw nb"));
			PatternSet.Add('J', Pattern.Parse("nb nw nb nw wb ww wb nw nb"));
			PatternSet.Add('K', Pattern.Parse("wb nw nb nw nb nw nb ww wb"));
			PatternSet.Add('L', Pattern.Parse("nb nw wb nw nb nw nb ww wb"));
			PatternSet.Add('M', Pattern.Parse("wb nw wb nw nb nw nb ww nb"));
			PatternSet.Add('N', Pattern.Parse("nb nw nb nw wb nw nb ww wb"));
			PatternSet.Add('O', Pattern.Parse("wb nw nb nw wb nw nb ww nb"));
			PatternSet.Add('P', Pattern.Parse("nb nw wb nw wb nw nb ww nb"));
			PatternSet.Add('Q', Pattern.Parse("nb nw nb nw nb nw wb ww wb"));
			PatternSet.Add('R', Pattern.Parse("wb nw nb nw nb nw wb ww nb"));
			PatternSet.Add('S', Pattern.Parse("nb nw wb nw nb nw wb ww nb"));
			PatternSet.Add('T', Pattern.Parse("nb nw nb nw wb nw wb ww nb"));
			PatternSet.Add('U', Pattern.Parse("wb ww nb nw nb nw nb nw wb"));
			PatternSet.Add('V', Pattern.Parse("nb ww wb nw nb nw nb nw wb"));
			PatternSet.Add('W', Pattern.Parse("wb ww wb nw nb nw nb nw nb"));
			PatternSet.Add('X', Pattern.Parse("nb ww nb nw wb nw nb nw wb"));
			PatternSet.Add('Y', Pattern.Parse("wb ww nb nw wb nw nb nw nb"));
			PatternSet.Add('Z', Pattern.Parse("nb ww wb nw wb nw nb nw nb"));
			PatternSet.Add('-', Pattern.Parse("nb ww nb nw nb nw wb nw wb"));
			PatternSet.Add('.', Pattern.Parse("wb ww nb nw nb nw wb nw nb"));
			PatternSet.Add(' ', Pattern.Parse("nb ww wb nw nb nw wb nw nb"));
			PatternSet.Add('*', Pattern.Parse("nb ww nb nw wb nw wb nw nb"));
			PatternSet.Add('$', Pattern.Parse("nb ww nb ww nb ww nb nw nb"));
			PatternSet.Add('/', Pattern.Parse("nb ww nb ww nb nw nb ww nb"));
			PatternSet.Add('+', Pattern.Parse("nb ww nb nw nb ww nb ww nb"));
			PatternSet.Add('%', Pattern.Parse("nb nw nb ww nb ww nb ww nb"));
		}

		public override CodedValueCollection GetCodes(string value)
		{
			value = value.Trim('*');
			value = "*" + value.ToUpper() + "*";

			return base.GetCodes(value);
		}

		public override string GetDisplayText(string value)
		{
			value = value.Trim('*');
			return "*" + value.ToUpper() + "*";
		}

		public override int CalculateWidth(BarcodeSettings settings, CodedValueCollection codes)
		{
			return codes.Count * ((3 * settings.WideWidth) + (6 * settings.NarrowWidth) + settings.ModulePadding);
		}
	}
}


<|start_filename|>Barcode Writer/ReedSolomon.cs<|end_filename|>
﻿using System;

namespace Barcodes
{
    /// <summary>
    /// Calculates Reed Solomon Error Correction codes
    /// </summary>
    public class ReedSolomon
    {
//        public const short QRCODE_INITIALISER = 0x11D;
        private const int SYMBOLSIZE = 0xff;

        private byte[] _LogTable;
        private byte[] _AntiLogTable;
        //private byte[] _Coefficients;
        //private int _G;
        private IInitialiser _Initialiser;
        private CoefficientsCollection _Coefficients;

        public ReedSolomon(IInitialiser initialiser)
        {
            if (initialiser == null)
                throw new ArgumentNullException("initialiser", "Polynomial initialiser cannot be null.");

            _Initialiser = initialiser;
            InitaliseLogTables();
            _Coefficients = new CoefficientsCollection();
        }

        /// <summary>
        /// Initialise the log & anti-log tables
        /// </summary>
        private void InitaliseLogTables()
        {
            _LogTable = new byte[SYMBOLSIZE + 1];
            _AntiLogTable = new byte[SYMBOLSIZE];

            for (int p = 1, v = 0; v < SYMBOLSIZE; v++)
            {
                _AntiLogTable[v] = (byte)p;
                _LogTable[p] = (byte)v;
                p <<= 1;
                if ((p > SYMBOLSIZE))
                    p ^= _Initialiser.G;
            }
        }

        /// <summary>
        /// Initialise the coefficients table according to the desired number of codewords.
        /// </summary>
        /// <param name="numberofSymbols">number of error correction codewords desired</param>
        /// <param name="firstTerm">intilises the polynomial, usually 1</param>
        private void InitialiseCoefficients(int numberofSymbols)
        {
            if (_Coefficients.Contains(numberofSymbols))
                return;

            byte[] tmp = new byte[numberofSymbols + 1];
            int firstTerm = 1;

            tmp[0] = 1;
            for (int i = 1; i <= numberofSymbols; i++)
            {
                tmp[i] = 1;

                for (int k = i - 1; k > 0; k--)
                {
                    if (tmp[k] != 0)
                        tmp[k] = _AntiLogTable[(_LogTable[tmp[k]] + firstTerm) % SYMBOLSIZE];

                    tmp[k] ^= tmp[k - 1];
                }

                tmp[0] = _AntiLogTable[(_LogTable[tmp[0]] + firstTerm) % SYMBOLSIZE];
                firstTerm++;
            }

            byte[] result = new byte[tmp.Length - 1];
            Array.Copy(tmp, result, result.Length);
            _Coefficients.Add(result);
        }

        /// <summary>
        /// Calculates the error correction codewords from the data
        /// </summary>
        /// <param name="data">data to encode</param>
        /// <returns>array of codewords</returns>
        private byte[] GetCodewords(byte[] data, int level)
        {
            int EccCount = _Initialiser.GetECCCount(data.Length, level);
            InitialiseCoefficients(EccCount);

            byte[] result = new byte[EccCount];
            byte[] factors = _Coefficients[EccCount];
            int t = 0;

            for (int i = 0; i < data.Length; i++)
            {
                t = data[i] ^ result[result.Length - 1];

                for (int j = result.Length - 1; j > 0; j--)
                {
                    if (j == 0)
                        result[j] = result[j - 1];
                    else
                        result[j] = (byte)(result[j - 1] ^ _AntiLogTable[(_LogTable[t] + _LogTable[factors[j]]) % SYMBOLSIZE]);
                }

                if ((t & factors[0]) != 0)
                    result[0] = _AntiLogTable[(_LogTable[t] + _LogTable[factors[0]]) % SYMBOLSIZE];
                else
                    result[0] = 0;
            }

            return result;

        }

        /// <summary>
        /// Take a data array of bytes and adds the error codes to the end.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] Encode(byte[] data, int level)
        {
            byte[] tmp = GetCodewords(data, level);

            byte[] result = new byte[data.Length + tmp.Length];
            data.CopyTo(result, 0);

            for (int i = 0; i < tmp.Length; i++)
            {
                result[data.Length + tmp.Length - i - 1] = tmp[i];
            }

            return result;
        }
    }

    /// <summary>
    /// Defines the initialiser for the Reed Solomon functions
    /// </summary>
    public interface IInitialiser
    {
        int G { get; }
        int GetECCCount(int dataCount, int level);
    }

}


<|start_filename|>Barcode Writer/1D/Code3of9.cs<|end_filename|>
﻿#define MEASURE
using System;
using System.Collections.Generic;

namespace Barcodes
{
    /// <summary>
    /// Code 3 of 9 barcode generator
    /// </summary>
    public class Code3of9 : BarcodeBase
    {

        protected override void Init()
        {
            AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^[A-Z0-9-\\. \\$/+%]+$", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();

            PatternSet.Add('0', Pattern.Parse("nb nw nb ww wb nw wb nw nb"));
            PatternSet.Add('1', Pattern.Parse("wb nw nb ww nb nw nb nw wb"));
            PatternSet.Add('2', Pattern.Parse("nb nw wb ww nb nw nb nw wb"));
            PatternSet.Add('3', Pattern.Parse("wb nw wb ww nb nw nb nw nb"));
            PatternSet.Add('4', Pattern.Parse("nb nw nb ww wb nw nb nw wb"));
            PatternSet.Add('5', Pattern.Parse("wb nw nb ww wb nw nb nw nb"));
            PatternSet.Add('6', Pattern.Parse("nb nw wb ww wb nw nb nw nb"));
            PatternSet.Add('7', Pattern.Parse("nb nw nb ww nb nw wb nw wb"));
            PatternSet.Add('8', Pattern.Parse("wb nw nb ww nb nw wb nw nb"));
            PatternSet.Add('9', Pattern.Parse("nb nw wb ww nb nw wb nw nb"));
            PatternSet.Add('A', Pattern.Parse("wb nw nb nw nb ww nb nw wb"));
            PatternSet.Add('B', Pattern.Parse("nb nw wb nw nb ww nb nw wb"));
            PatternSet.Add('C', Pattern.Parse("wb nw wb nw nb ww nb nw nb"));
            PatternSet.Add('D', Pattern.Parse("nb nw nb nw wb ww nb nw wb"));
            PatternSet.Add('E', Pattern.Parse("wb nw nb nw wb ww nb nw nb"));
            PatternSet.Add('F', Pattern.Parse("nb nw wb nw wb ww nb nw nb"));
            PatternSet.Add('G', Pattern.Parse("nb nw nb nw nb ww wb nw wb"));
            PatternSet.Add('H', Pattern.Parse("wb nw nb nw nb ww wb nw nb"));
            PatternSet.Add('I', Pattern.Parse("nb nw wb nw nb ww wb nw nb"));
            PatternSet.Add('J', Pattern.Parse("nb nw nb nw wb ww wb nw nb"));
            PatternSet.Add('K', Pattern.Parse("wb nw nb nw nb nw nb ww wb"));
            PatternSet.Add('L', Pattern.Parse("nb nw wb nw nb nw nb ww wb"));
            PatternSet.Add('M', Pattern.Parse("wb nw wb nw nb nw nb ww nb"));
            PatternSet.Add('N', Pattern.Parse("nb nw nb nw wb nw nb ww wb"));
            PatternSet.Add('O', Pattern.Parse("wb nw nb nw wb nw nb ww nb"));
            PatternSet.Add('P', Pattern.Parse("nb nw wb nw wb nw nb ww nb"));
            PatternSet.Add('Q', Pattern.Parse("nb nw nb nw nb nw wb ww wb"));
            PatternSet.Add('R', Pattern.Parse("wb nw nb nw nb nw wb ww nb"));
            PatternSet.Add('S', Pattern.Parse("nb nw wb nw nb nw wb ww nb"));
            PatternSet.Add('T', Pattern.Parse("nb nw nb nw wb nw wb ww nb"));
            PatternSet.Add('U', Pattern.Parse("wb ww nb nw nb nw nb nw wb"));
            PatternSet.Add('V', Pattern.Parse("nb ww wb nw nb nw nb nw wb"));
            PatternSet.Add('W', Pattern.Parse("wb ww wb nw nb nw nb nw nb"));
            PatternSet.Add('X', Pattern.Parse("nb ww nb nw wb nw nb nw wb"));
            PatternSet.Add('Y', Pattern.Parse("wb ww nb nw wb nw nb nw nb"));
            PatternSet.Add('Z', Pattern.Parse("nb ww wb nw wb nw nb nw nb"));
            PatternSet.Add('-', Pattern.Parse("nb ww nb nw nb nw wb nw wb"));
            PatternSet.Add('.', Pattern.Parse("wb ww nb nw nb nw wb nw nb"));
            PatternSet.Add(' ', Pattern.Parse("nb ww wb nw nb nw wb nw nb"));
            PatternSet.Add('*', Pattern.Parse("nb ww nb nw wb nw wb nw nb"));
            PatternSet.Add('$', Pattern.Parse("nb ww nb ww nb ww nb nw nb"));
            PatternSet.Add('/', Pattern.Parse("nb ww nb ww nb nw nb ww nb"));
            PatternSet.Add('+', Pattern.Parse("nb ww nb nw nb ww nb ww nb"));
            PatternSet.Add('%', Pattern.Parse("nb nw nb ww nb ww nb ww nb"));
        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            value = value.Trim('*');
            if (!IsValidData(value))
                throw new ApplicationException("Invalid data for this barcode.");

            value = "*" + value.ToUpper() + "*";

            foreach (char item in value.ToCharArray())
            {
                codes.Add(item);
            }

            return value;
        }

        protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
        {
            width += (codes.Count * ((3 * settings.WideWidth) + (6 * settings.NarrowWidth)));
            return base.OnCalculateWidth(width, settings, codes);
        }
    }
}


<|start_filename|>Barcode Writer/1D/Code128.cs<|end_filename|>
﻿//#define MEASURE
using System;
using System.Collections.Generic;
using System.Text;

namespace Barcodes
{
    /// <summary>
    /// Code 128 barcode generator
    /// </summary>
    public class Code128 : BarcodeBase
    {
        private const int STOP = 106;
        protected int AiMarker = 156;

        protected override void Init()
        {
            DefaultSettings.ModulePadding = 0;

            AddChecksum += new EventHandler<AddChecksumEventArgs>(Code128_AddChecksum);
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();

            PatternSet.Add(0, ParseCode("212222"));
            PatternSet.Add(1, ParseCode("222122"));
            PatternSet.Add(2, ParseCode("222221"));
            PatternSet.Add(3, ParseCode("121223"));
            PatternSet.Add(4, ParseCode("121322"));
            PatternSet.Add(5, ParseCode("131222"));
            PatternSet.Add(6, ParseCode("122213"));
            PatternSet.Add(7, ParseCode("122312"));
            PatternSet.Add(8, ParseCode("132212"));
            PatternSet.Add(9, ParseCode("221213"));

            PatternSet.Add(10, ParseCode("221312"));
            PatternSet.Add(11, ParseCode("231212"));
            PatternSet.Add(12, ParseCode("112232"));
            PatternSet.Add(13, ParseCode("122132"));
            PatternSet.Add(14, ParseCode("122231"));
            PatternSet.Add(15, ParseCode("113222"));
            PatternSet.Add(16, ParseCode("123122"));
            PatternSet.Add(17, ParseCode("123221"));
            PatternSet.Add(18, ParseCode("223211"));
            PatternSet.Add(19, ParseCode("221132"));

            PatternSet.Add(20, ParseCode("221231"));
            PatternSet.Add(21, ParseCode("213212"));
            PatternSet.Add(22, ParseCode("223112"));
            PatternSet.Add(23, ParseCode("312131"));
            PatternSet.Add(24, ParseCode("311222"));
            PatternSet.Add(25, ParseCode("321122"));
            PatternSet.Add(26, ParseCode("321221"));
            PatternSet.Add(27, ParseCode("312212"));
            PatternSet.Add(28, ParseCode("322112"));
            PatternSet.Add(29, ParseCode("322211"));

            PatternSet.Add(30, ParseCode("212123"));
            PatternSet.Add(31, ParseCode("212321"));
            PatternSet.Add(32, ParseCode("232121"));
            PatternSet.Add(33, ParseCode("111323"));
            PatternSet.Add(34, ParseCode("131123"));
            PatternSet.Add(35, ParseCode("131321"));
            PatternSet.Add(36, ParseCode("112313"));
            PatternSet.Add(37, ParseCode("132113"));
            PatternSet.Add(38, ParseCode("132311"));
            PatternSet.Add(39, ParseCode("211313"));

            PatternSet.Add(40, ParseCode("231113"));
            PatternSet.Add(41, ParseCode("231311"));
            PatternSet.Add(42, ParseCode("112133"));
            PatternSet.Add(43, ParseCode("112331"));
            PatternSet.Add(44, ParseCode("132131"));
            PatternSet.Add(45, ParseCode("113123"));
            PatternSet.Add(46, ParseCode("113321"));
            PatternSet.Add(47, ParseCode("133121"));
            PatternSet.Add(48, ParseCode("313121"));
            PatternSet.Add(49, ParseCode("211331"));

            PatternSet.Add(50, ParseCode("231131"));
            PatternSet.Add(51, ParseCode("213113"));
            PatternSet.Add(52, ParseCode("213311"));
            PatternSet.Add(53, ParseCode("213131"));
            PatternSet.Add(54, ParseCode("311123"));
            PatternSet.Add(55, ParseCode("311321"));
            PatternSet.Add(56, ParseCode("331121"));
            PatternSet.Add(57, ParseCode("312113"));
            PatternSet.Add(58, ParseCode("312311"));
            PatternSet.Add(59, ParseCode("332111"));

            PatternSet.Add(60, ParseCode("314111"));
            PatternSet.Add(61, ParseCode("221411"));
            PatternSet.Add(62, ParseCode("431111"));
            PatternSet.Add(63, ParseCode("111224"));
            PatternSet.Add(64, ParseCode("111422"));
            PatternSet.Add(65, ParseCode("121124"));
            PatternSet.Add(66, ParseCode("121421"));
            PatternSet.Add(67, ParseCode("141122"));
            PatternSet.Add(68, ParseCode("141221"));
            PatternSet.Add(69, ParseCode("112214"));

            PatternSet.Add(70, ParseCode("112412"));
            PatternSet.Add(71, ParseCode("122114"));
            PatternSet.Add(72, ParseCode("122411"));
            PatternSet.Add(73, ParseCode("142112"));
            PatternSet.Add(74, ParseCode("142211"));
            PatternSet.Add(75, ParseCode("241211"));
            PatternSet.Add(76, ParseCode("221114"));
            PatternSet.Add(77, ParseCode("413111"));
            PatternSet.Add(78, ParseCode("241112"));
            PatternSet.Add(79, ParseCode("134111"));

            PatternSet.Add(80, ParseCode("111242"));
            PatternSet.Add(81, ParseCode("121142"));
            PatternSet.Add(82, ParseCode("121241"));
            PatternSet.Add(83, ParseCode("114212"));
            PatternSet.Add(84, ParseCode("124112"));
            PatternSet.Add(85, ParseCode("124211"));
            PatternSet.Add(86, ParseCode("411212"));
            PatternSet.Add(87, ParseCode("421112"));
            PatternSet.Add(88, ParseCode("421211"));
            PatternSet.Add(89, ParseCode("212141"));

            PatternSet.Add(90, ParseCode("214121"));
            PatternSet.Add(91, ParseCode("412121"));
            PatternSet.Add(92, ParseCode("111143"));
            PatternSet.Add(93, ParseCode("111341"));
            PatternSet.Add(94, ParseCode("131141"));
            PatternSet.Add(95, ParseCode("114113"));
            PatternSet.Add(96, ParseCode("114311"));
            PatternSet.Add(97, ParseCode("411113"));
            PatternSet.Add(98, ParseCode("411311"));
            PatternSet.Add(99, ParseCode("113141"));

            PatternSet.Add(100, ParseCode("114131"));
            PatternSet.Add(101, ParseCode("311141"));
            PatternSet.Add(102, ParseCode("411131"));
            PatternSet.Add(103, ParseCode("211412"));
            PatternSet.Add(104, ParseCode("211214"));
            PatternSet.Add(105, ParseCode("211232"));

            //STOP pattern
            PatternSet.Add(STOP, ParseCode("2331112"));
        }

        /// <summary>
        /// Converts shorthand listed module format into a pattern
        /// </summary>
        /// <param name="value">shorthand format - number of black or white bars to draw</param>
        /// <returns>pattern representing format</returns>
        private Pattern ParseCode(string value)
        {
            List<Elements> list = new List<Elements>();

            int i = 0;
            int tmp;
            while (i < value.Length)
            {
                tmp = int.Parse(value.Substring(i, 1));

                for (int j = 0; j < tmp; j++)
                {
                    list.Add((Elements)(i % 2) + 2);
                }
                i++;
            }

            return new Pattern(list.ToArray());
        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            char variant = Code128Helper.StartVariantB;
            int i = 0;
            bool shifted = false;

            StringBuilder ParsedText = new StringBuilder();

            if (value[0] < 128)
                value = AutoFormat(value);

            if (value[0] == Code128Helper.StartVariantA)
            {
                variant = Code128Helper.CODEA;
                codes.Add((int)Code128Helper.StartVariantA - 50);
                i++;
            }
            else if (value[0] == Code128Helper.StartVariantB)
            {
                variant = Code128Helper.CODEB;
                codes.Add((int)Code128Helper.StartVariantB - 50);
                i++;
            }
            else if (value[0] == Code128Helper.StartVariantC)
            {
                variant = Code128Helper.CODEC;
                codes.Add((int)Code128Helper.StartVariantC - 50);
                i++;
            }

            int tmp;
            do
            {
                if (value[i] == AiMarker)
                {
                    ParsedText.Append(AiMarker);
                    i++;
                }
                if (shifted)
                    if (variant == Code128Helper.CODEA)
                        variant = Code128Helper.CODEB;
                    else
                        variant = Code128Helper.CODEA;

                if (variant == Code128Helper.CODEA)
                {
                    tmp = EncodeCodeA(value[i], ParsedText);

                    if (value[i] == Code128Helper.CODEB || value[i] == Code128Helper.CODEC)
                        variant = value[i];

                    i++;
                }
                else if (variant == Code128Helper.CODEB)
                {
                    tmp = EncodeCodeB(value[i], ParsedText);

                    if (value[i] == Code128Helper.CODEA || value[i] == Code128Helper.CODEC)
                        variant = value[i];

                    i++;
                }
                else
                {
                    if (value[i] == Code128Helper.CODEA || value[i] == Code128Helper.CODEB)
                    {
                        tmp = (int)value[i] - 50;
                        variant = value[i];
                        i++;
                    }
                    else if (value[i] == Code128Helper.FNC1)
                    {
                        tmp = (int)value[i] - 50;
                        i++;
                    }
                    else
                    {
                        tmp = EncodeCodeC(value.Substring(i, 2), ParsedText);
                        i += 2;
                    }
                }

                codes.Add(tmp);

                if (shifted)
                {
                    if (variant == Code128Helper.CODEA)
                        variant = Code128Helper.CODEB;
                    else
                        variant = Code128Helper.CODEA;
                }

                shifted = (tmp == 98 && variant != Code128Helper.CODEC);

            } while (i < value.ToCharArray().Length);

            codes.Add(STOP);

            return ParsedText.ToString();
        }

        /// <summary>
        /// Encode a character using type A encoding
        /// </summary>
        /// <param name="value">value to encode</param>
        /// <param name="parsedText">string builder to hold the encoded text</param>
        /// <returns>value of the encoded character</returns>
        private int EncodeCodeA(char value, StringBuilder parsedText)
        {
            int tmp =(int)value;

            if (tmp > 31 && tmp < 96)
            {
                parsedText.Append(value);
                return tmp - 32;
            }
            if (tmp >= 0 && tmp < 32)
                return tmp + 64;

            if (tmp >= Code128Helper.FNC3 && tmp <= Code128Helper.FNC1)
                return tmp - 50;

            throw new ApplicationException("Unsupported character encountered");
        }

        /// <summary>
        /// Encode a character using type B encoding
        /// </summary>
        /// <param name="value">value to encode</param>
        /// <param name="parsedText">string builder to hold the encoded text</param>
        /// <returns>value of the encoded character</returns>
        private int EncodeCodeB(char value, StringBuilder parsedText)
        {
            int tmp = (int)value;

            if (tmp > 31 && tmp < 127)
            {
                parsedText.Append(value);
                return tmp - 32;
            }
            if (tmp == 127)
                return tmp - 32;

            if (value >= Code128Helper.FNC3 && value <= Code128Helper.FNC1)
                return tmp - 50;

            throw new ApplicationException("Unsupported character encountered");
        }

        /// <summary>
        /// Encode a character using type A encoding
        /// </summary>
        /// <param name="value">value to encode</param>
        /// <param name="parsedText">string builder to hold the encoded text</param>
        /// <returns>value of the encoded character</returns>
        private int EncodeCodeC(string value, StringBuilder parsedText)
        {
            int tmp = int.Parse(value);
            if (tmp < 0 || tmp > 99)
                throw new ApplicationException("Unexpected value encountered.");

            parsedText.Append(value);
            return tmp;
        }

        /// <summary>
        /// Handles the add checksum event
        /// </summary>
        /// <param name="sender">the barcode instance raising the event</param>
        /// <param name="e">argument for the event</param>
        void Code128_AddChecksum(object sender, AddChecksumEventArgs e)
        {
            int total = 0;

            for (int i = 0; i < e.Codes.Count - 1; i++)
            {
                if (i == 0)
                    total = e.Codes[i];
                else
                    total += e.Codes[i] * i;
            }

            e.Codes.Insert(e.Codes.Count - 1, total % 103);
        }

        protected string AutoFormat(string value)
        {
            StringBuilder s = new StringBuilder();

            int i = 0;
            int v = 0;
            if (value[0] < ' ')
            {
                v = Code128Helper.CODEA;
                s.Append(Code128Helper.StartVariantA);
            }
            else if (System.Text.RegularExpressions.Regex.IsMatch(value, "^\\d\\d"))
            {
                v = Code128Helper.CODEC;
                s.Append(Code128Helper.StartVariantC);
            }
            else
            {
                v = Code128Helper.CODEB;
                s.Append(Code128Helper.StartVariantB);
            }

            bool switched = false;
            do
            {
                if (value[i] < ' ' && v != Code128Helper.CODEA)
                {
                    v = Code128Helper.CODEA;
                    s.Append(Code128Helper.CODEA);
                }
                else if (value[i] > '_' && value[i] < 128 && v != Code128Helper.CODEB)
                {
                    v = Code128Helper.CODEB;
                    s.Append(Code128Helper.CODEB);
                }
                else if (char.IsNumber(value[i]))
                {
                    if (i + 1 < value.Length && char.IsNumber(value[i + 1]) && v != Code128Helper.CODEC)
                    {
                        v = Code128Helper.CODEC;
                        s.Append(Code128Helper.CODEC);

                    }

                    if (i + 1 >= value.Length && v == Code128Helper.CODEC)
                    {
                        v = Code128Helper.CODEB;
                        s.Append(Code128Helper.CODEB);
                    }
                }
                if (value[i] == Code128Helper.CODEA || value[i] == Code128Helper.CODEB || value[i] == Code128Helper.CODEC)
                    v = value[i];

                if (switched || value[i] == Code128Helper.SHIFT)
                {
                    v = v == Code128Helper.CODEA ? Code128Helper.CODEB : Code128Helper.CODEA;
                    switched = !switched;
                }

                s.Append(value[i]);
                i++;
                if (v == Code128Helper.CODEC)
                {
                    s.Append(value[i]);
                    i++;
                }

            } while (i < value.Length);

            return s.ToString();
        }

        protected override void OnBeforeDrawCode(State state)
        {
            state.Left += 10 * state.Settings.NarrowWidth;
            base.OnBeforeDrawCode(state);
        }

        protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
        {
             //10 narrow space queit zone + 2 narrow bars for the STOP
            width += (codes.Count * 11 * settings.NarrowWidth) + (2 * 10 * settings.NarrowWidth) + (2 * settings.NarrowWidth);

            return base.OnCalculateWidth(width, settings, codes);
        }

        public override bool IsValidData(string value)
        {
            foreach (char item in value.ToCharArray())
            {
                if (item > 127)
                    return false;
            }

            return true;
        }

    }
}


<|start_filename|>Barcode Writer/Pattern.cs<|end_filename|>
﻿using System;
using System.Text.RegularExpressions;

namespace Barcodes
{
	/// <summary>
	/// Elements of a pattern
	/// </summary>
	public enum Elements
	{
		WideBlack,
		WideWhite,
		NarrowBlack,
		NarrowWhite,
		Tracker,
		Ascender,
		Descender
	}

	/// <summary>
	/// An individual module or pattern in a barcode
	/// </summary>
	public class Pattern
	{
		private Elements[] _State;

		public Elements[] Elements
		{
			get { return _State; }
		}

		/// <summary>
		/// Gets or sets the count of wide bars in the module
		/// </summary>
		internal int WideCount
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the count of narrow bars in the module
		/// </summary>
		internal int NarrowCount
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the count of black bars in the module
		/// </summary>
		internal int BlackCount
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the count of white bars in the module
		/// </summary>
		internal int WhiteCount
		{
			get;
			set;
		}

		public Pattern(Elements[] pattern)
			: this()
		{
			_State = pattern;

			foreach (Elements item in _State)
			{
				if ((int)item > 1)
					NarrowCount++;
				else
					WideCount++;
				if ((int)item % 2 == 0)
					BlackCount++;
				else
					WhiteCount++;
			}
		}

		private Pattern()
		{
		}

		/// <summary>
		/// Parse a textual pattern description into a module
		/// (0 - white, 1 - black)
		/// (ww - wide white, wb - wide black, nw - narrow white, nb - narrow black)
		/// (t - tracker, a - ascender, d - descender, f - full height)
		/// </summary>
		/// <param name="pattern">string to encode</param>
		/// <returns>pattern object</returns>
		public static Pattern Parse(string pattern)
		{
			Pattern result = new Pattern();

			if (Regex.IsMatch(pattern, "^[01]+$"))
				result.ParseBinary(pattern);
			else if (Regex.IsMatch(pattern, "^((0|1|[wn][wb]) ?)+$"))
				result.ParseFull(pattern);
			else if (Regex.IsMatch(pattern, "^[tadf]+$"))
				result.ParsePost(pattern);

			return result;
		}

		/// <summary>
		/// Parse the pattern using a space seperated description
		/// </summary>
		/// <param name="pattern">pattern to encode</param>
		private void ParseFull(string pattern)
		{
			string[] parts = pattern.Split(' ');
			_State = new Elements[parts.Length];
			
			for (int i = 0; i < parts.Length; i++)
			{
				switch (parts[i])
				{
					case "ww":
						AddBar(Barcodes.Elements.WideWhite, i);
						break;
					case "wb":
						AddBar(Barcodes.Elements.WideBlack, i);
						break;
					case "0":
					case "nw":
						AddBar(Barcodes.Elements.NarrowWhite, i);
						break;
					case "1":
					case "nb":
						AddBar(Barcodes.Elements.NarrowBlack, i);
						break;
					default:
						throw new ApplicationException("Unknown pattern element.");
				}
			}

		}

		/// <summary>
		/// Parse using a binary pattern
		/// </summary>
		/// <param name="pattern">pattern to encode</param>
		private void ParseBinary(string value)
		{
			_State = new Elements[value.Length];

			for (int i = 0; i < value.Length; i++)
			{
				switch (value[i])
				{
					case '0':
						AddBar(Barcodes.Elements.NarrowWhite, i);
						break;
					case '1':
						AddBar(Barcodes.Elements.NarrowBlack, i);
						break;
				}
			}

		}

		/// <summary>
		/// Parse using 4-state encodings
		/// </summary>
		/// <param name="pattern">pattern to encode</param>
		private void ParsePost(string pattern)
		{
			_State = new Elements[(pattern.Length * 2)];

			for (int i = 0; i < pattern.Length; i++)
			{
				switch (pattern[i])
				{
					case 't':
						AddBar(Barcodes.Elements.Tracker, i * 2);
						break;
					case 'a':
						AddBar(Barcodes.Elements.Ascender, i * 2);
						break;
					case 'd':
						AddBar(Barcodes.Elements.Descender, i * 2);
						break;
					case 'f':
						AddBar(Barcodes.Elements.NarrowBlack, i * 2);
						break;
				}

				AddBar(Barcodes.Elements.WideWhite, (i * 2) + 1);

			}
		}

		/// <summary>
		/// Add a bar to this pattern
		/// </summary>
		/// <param name="bar">bar to add</param>
		/// <param name="index">index to add bar at</param>
		private void AddBar(Elements bar, int index)
		{
			_State[index] = bar;

			switch (bar)
			{
				case Barcodes.Elements.WideBlack:
					WideCount++;
					BlackCount++;
					break;
				case Barcodes.Elements.WideWhite:
					WideCount++;
					WhiteCount++;
					break;
				case Barcodes.Elements.NarrowWhite:
					NarrowCount++;
					WhiteCount++;
					break;
				case Barcodes.Elements.Tracker:
				case Barcodes.Elements.Ascender:
				case Barcodes.Elements.Descender:
				case Barcodes.Elements.NarrowBlack:
					NarrowCount++;
					BlackCount++;
					break;
			}
		}

		//public static Pattern Parse(char[] pattern)
		//{
		//    Pattern result = new Pattern();
		//    result._State = new Elements[pattern.Length];
		//    result.NarrowCount = pattern.Length;

		//    for (int i = 0; i < pattern.Length; i++)
		//    {
		//        if (pattern[i] == '0')
		//            result._State[i] = Elements.NarrowWhite;
		//        else if (pattern[i] == '1')
		//            result._State[i] = Elements.NarrowBlack;
		//        else
		//            throw new ApplicationException("Unknown pattern element found.");
		//    }

		//    return result;
		//}

		///// <summary>
		///// Draw the module as series of black rectangles
		///// </summary>
		///// <param name="settings">settings to use</param>
		///// <returns>array of black rectangles</returns>
		//internal IEnumerable<Rectangle> Paint(BarcodeSettings settings)
		//{
		//    List<Rectangle> result = new List<Rectangle>();

		//    float offset = (settings.MediumHeight - settings.ShortHeight);
		//    float left = 0;
		//    Rectangle rect;
		//    foreach (Elements item in _State)
		//    {
		//        switch (item)
		//        {
		//            case Elements.WideBlack:
		//                rect = new RectangleF(left, 0, settings.WideWidth, settings.BarHeight)
		//                left += settings.WideWidth;

		//                result.Add(rect);
		//                break;
		//            case Elements.WideWhite:
		//                left += settings.WideWidth;
		//                break;
		//            case Elements.NarrowBlack:
		//                rect = new Rectangle(left, 0, settings.NarrowWidth, settings.BarHeight);
		//                left += settings.NarrowWidth;

		//                result.Add(rect);
		//                break;
		//            case Elements.NarrowWhite:
		//                left += settings.NarrowWidth;
		//                break;
		//            case Elements.Tracker:
		//                rect = new Rectangle(left, offset, settings.NarrowWidth, settings.ShortHeight);
		//                left += settings.NarrowWidth;
		//                result.Add(rect);
		//                break;
		//            case Elements.Ascender:
		//                rect = new Rectangle(left, 0, settings.NarrowWidth, settings.MediumHeight);
		//                left += settings.NarrowWidth;
		//                result.Add(rect);
		//                break;
		//            case Elements.Descender:
		//                rect = new Rectangle(left, offset, settings.NarrowWidth, settings.MediumHeight);
		//                left += settings.NarrowWidth;
		//                result.Add(rect);
		//                break;
		//        }                
		//    }

		//    return result;
		//}
	}
}


<|start_filename|>Barcode Writer/State.cs<|end_filename|>
﻿using System.Drawing;

namespace Barcodes
{
	/// <summary>
	/// Drawing state used to pass between methods
	/// </summary>
	public class State
	{
		/// <summary>
		/// Gets or sets the current left position in pixels
		/// </summary>
		public int Left
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the current top position in pixels
		/// </summary>
		public int Top
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the current canvas
		/// </summary>
		public Graphics Canvas
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the current barcode settings
		/// </summary>
		public BarcodeSettings Settings
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets or sets the module to be drawn
		/// </summary>
		public char ModuleValue
		{
			get;
			set;
		}

		public string Text
		{
			get;
			set;
		}

		public CodedValueCollection Codes
		{
			get;
			set;
		}

		public State(BarcodeSettings settings, int left, int top)
		{
			Left = left;
			Top = top;
			Settings = settings;
		}
	}
}


<|start_filename|>Barcodes2/Definitions/Postal/Postnet.cs<|end_filename|>
﻿using System.Collections.Generic;

namespace Barcodes2.Definitions.Postal
{
	public class Postnet : DefaultDefinition
	{
		private const int STARTSTOP = 11;

		public Postnet()
			: base()
		{
			IsChecksumRequired = true;
		}

		protected override System.Text.RegularExpressions.Regex GetRegex()
		{
			return new System.Text.RegularExpressions.Regex(@"^\d{5}((\s|-)?\d{4}((\s|-)?\d{2})?)?$");
		}

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			PatternSet.Add(0, Pattern.Parse("aattt"));
			PatternSet.Add(1, Pattern.Parse("tttaa"));
			PatternSet.Add(2, Pattern.Parse("ttata"));
			PatternSet.Add(3, Pattern.Parse("ttaat"));
			PatternSet.Add(4, Pattern.Parse("tatta"));
			PatternSet.Add(5, Pattern.Parse("tatat"));
			PatternSet.Add(6, Pattern.Parse("taatt"));
			PatternSet.Add(7, Pattern.Parse("attta"));
			PatternSet.Add(8, Pattern.Parse("attat"));
			PatternSet.Add(9, Pattern.Parse("atatt"));

			PatternSet.Add(STARTSTOP, Pattern.Parse("a"));
		}

		public override void TransformSettings(BarcodeSettings settings)
		{
			base.TransformSettings(settings);

			settings.ModulePadding = 0;
			settings.WideWidth = 2 * settings.NarrowWidth;
			settings.IsTextShown = false;
			settings.IsChecksumCalculated = true;

			settings.MediumHeight = (int)((settings.BarHeight / 3f) * 2f);
			settings.ShortHeight = settings.BarHeight / 3;
		}

		public override string AddChecksum(string value, CodedValueCollection codes)
		{
			int total = 0;
			for (int i = 1; i < codes.Count - 1; i++)
			{
				total += codes[i];
			}

			total = total % 10;

			codes.Insert(codes.Count - 1, total == 0 ? 0 : 10 - total);

			return value;
		}

		public override CodedValueCollection GetCodes(string value)
		{
			var codes = new CodedValueCollection();

			value = value.Replace(" ", "").Replace("-", "");

			for (int i = 0; i < value.Length; i++)
			{
				codes.Add(int.Parse(value.Substring(i, 1)));
			}

			codes.Insert(0, STARTSTOP);
			codes.Add(STARTSTOP);

			return codes;
		}

		public override int CalculateWidth(BarcodeSettings settings, CodedValueCollection codes)
		{
			//var width = (((settings.NarrowWidth + settings.WideWidth) * 5) * (codes.Count - 2)) + (2 * settings.NarrowWidth) + settings.WideWidth;

			return base.CalculateWidth(settings, codes);
		}
	}
}


<|start_filename|>Barcodes2/Definitions/Postal/CPC.cs<|end_filename|>
﻿using System.Collections.Generic;
using System.Linq;

namespace Barcodes2.Definitions.Postal
{
	public class CPC : DefaultDefinition
	{
		private const int ALIGNMENTBAR = 0x100;
		private const int ODDCOUNT = 0x101;

		private Dictionary<string, int> _Lookup;

		public CPC()
			:base()
		{
			CreateLookups();
		}

		protected override System.Text.RegularExpressions.Regex GetRegex()
		{
			return new System.Text.RegularExpressions.Regex("^[A-Z-[DFIOQU]]\\d[A-Z-[DFIOQU]] \\d[A-Z-[DFIOQU]]\\d$");
		}

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			PatternSet.Add(0, Pattern.Parse("nw nw nw"));
			PatternSet.Add(1, Pattern.Parse("nw nb nw"));
			PatternSet.Add(ALIGNMENTBAR, Pattern.Parse("nw nb nw"));
			PatternSet.Add(ODDCOUNT, Pattern.Parse("nw nw nw"));
		}

		/// <summary>
		/// Create the conversion table
		/// </summary>
		private void CreateLookups()
		{
			_Lookup = new Dictionary<string, int>();
			_Lookup.Add("A", 0x07);
			_Lookup.Add("B", 0x0C);
			_Lookup.Add("C", 0x0B);
			_Lookup.Add("E", 0x0D);
			_Lookup.Add("G", 0x09);
			_Lookup.Add("H", 0x08);
			_Lookup.Add("J", 0x06);
			_Lookup.Add("K", 0x03);
			_Lookup.Add("L", 0x02);
			_Lookup.Add("M", 0x04);
			_Lookup.Add("N", 0x16);
			_Lookup.Add("P", 0x1C);
			_Lookup.Add("R", 0x05);
			_Lookup.Add("S", 0x0A);
			_Lookup.Add("T", 0x14);
			_Lookup.Add("V", 0x11);
			_Lookup.Add("W", 0x18);
			_Lookup.Add("X", 0x13);
			_Lookup.Add("Y", 0x0E);
			_Lookup.Add("Z", 0x1A);

			int[] numbers = new int[] { 0xA, 0x2, 0x9, 0x3, 0xB, 0x5, 0x6, 0x7, 0xD, 0xE };
			for (int i = 0; i < numbers.Length; i++)
			{
				_Lookup.Add(i.ToString(), numbers[i]);
			}

			_Lookup.Add("X0", 0x11);
			_Lookup.Add("X1", 0x14);
			_Lookup.Add("X2", 0x1C);
			_Lookup.Add("X3", 0x41);
			_Lookup.Add("X4", 0x44);
			_Lookup.Add("X5", 0x4C);
			_Lookup.Add("X6", 0xC1);
			_Lookup.Add("X7", 0xC4);
			_Lookup.Add("X8", 0xCC);
			_Lookup.Add("X9", 0x84);
		}

		public override void TransformSettings(BarcodeSettings settings)
		{
			base.TransformSettings(settings);

			settings.WideWidth = 2 * settings.NarrowWidth;
			settings.IsTextShown = false;
			settings.ModulePadding = 0;
		}

		public override CodedValueCollection GetCodes(string value)
		{
			var codes = new CodedValueCollection();

			value = value.Replace(" ", "").ToUpper();

			var index = ToBinary(ParsePair(value.Substring(0, 2)), 0, 8, codes);
			index = ToBinary(_Lookup[value.Substring(2, 1)], index, 5, codes);
			index = ToBinary(_Lookup[value.Substring(3, 1)], index, 4, codes);
			ToBinary(ParsePair(value.Substring(4, 2)), index, 8, codes);

			int p = codes.Sum() + 1;
			codes.Add(ALIGNMENTBAR);
			if (p % 2 == 0)
				codes.Insert(0, ALIGNMENTBAR);
			else
				codes.Insert(0, ODDCOUNT);

			return codes;
		}

		private int ToBinary(int value, int index, int count, CodedValueCollection codes)
		{
			for (int i = 0; i < count; i++)
			{
				codes.Insert(index, value % 2);
				value >>= 1;
			}

			return index + count;
		}

		/// <summary>
		/// Take a double digit pair & get it's hex value from the conversion table and rules
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		private int ParsePair(string value)
		{
			if (_Lookup.ContainsKey(value))
				return _Lookup[value];

			int ho = _Lookup[value.Substring(0, 1)];
			int lo = _Lookup[value.Substring(1, 1)];
			if (ho < 0x11)
				return (ho * 0x10) + lo;
			else if (ho == 0x11)
				return 0x10 + lo;
			else if (ho == 0x1a)
				return lo * 0x10;
			else if (ho == 0x16)
				return (lo * 0x10) + 1;
			else
				return (ho - 0x10) + (lo * 0x10);
		}
	}
}


<|start_filename|>WebControls/GeneratorService.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Barcodes.Web
{
	/// <summary>
	/// Image generator interface
	/// </summary>
	public interface IGeneratorService
	{
		/// <summary>
		/// Create a barcode image from the specifed settings
		/// </summary>
		/// <param name="settings">settings</param>
		/// <returns>image stream</returns>
		System.IO.Stream GetBarcode(RequestSettings settings);
	}

	/// <summary>
	/// Creates an image from the specifed settings
	/// </summary>
	public class GeneratorService : IGeneratorService
	{
		private Dictionary<BarcodeFormats, BarcodeBase> _Barcodes;
		private object _Lock;

		public GeneratorService()
		{
			_Barcodes = new Dictionary<BarcodeFormats, BarcodeBase>();
			_Lock = new object();
		}

		public System.IO.Stream GetBarcode(RequestSettings settings)
		{
			BarcodeBase b = GetBarcode(settings.BarcodeFormat);
			if (!b.IsValidData(settings.Data))
				throw new ArgumentException("The data is not valid for the requested barcode");

			BarcodeSettings bs = b.DefaultSettings.Copy();
			bs.Size = settings.Size;
			bs.Scale = settings.Scale;
			bs.LeftMargin = settings.LeftMargin;
			bs.TopMargin = settings.TopMargin;
			bs.RightMargin = settings.RightMargin;
			bs.BottomMargin = settings.BottomMargin;

			System.Drawing.Bitmap result = b.Generate(settings.Data, bs);
			System.IO.MemoryStream resultstrm = new System.IO.MemoryStream();
			result.Save(resultstrm, settings.Format);

			return resultstrm;
		}

		private BarcodeBase GetBarcode(BarcodeFormats format)
		{
			if (_Barcodes.ContainsKey(format))
				return _Barcodes[format];

			lock (_Lock)
			{
				if (_Barcodes.ContainsKey(format))
					return _Barcodes[format];

				switch (format)
				{
					case BarcodeFormats.Code3of9:
						_Barcodes.Add(format, new Code3of9());
						break;
					case BarcodeFormats.Code128:
						_Barcodes.Add(format, new Code128());
						break;
					case BarcodeFormats.Codabar:
						_Barcodes.Add(format, new Codabar());
						break;
					case BarcodeFormats.Code11:
						_Barcodes.Add(format, new Code11());
						break;
					case BarcodeFormats.Code2of5:
						_Barcodes.Add(format, new Code2of5());
						break;
					case BarcodeFormats.Code93:
						_Barcodes.Add(format, new Code93());
						break;
					case BarcodeFormats.EAN128:
						_Barcodes.Add(format, new EAN128());
						break;
					case BarcodeFormats.EAN13:
						_Barcodes.Add(format, new EAN13());
						break;
					case BarcodeFormats.EAN8:
						_Barcodes.Add(format, new EAN8());
						break;
					case BarcodeFormats.Extended3of9:
						_Barcodes.Add(format, new ExtendedCode3of9());
						break;
					case BarcodeFormats.Interleaved2of5:
						_Barcodes.Add(format, new Interleaved2of5());
						break;
					case BarcodeFormats.UPC:
						_Barcodes.Add(format, new UPC());
						break;
					case BarcodeFormats.UPC2:
						_Barcodes.Add(format, new UPC2());
						break;
					case BarcodeFormats.UPC5:
						_Barcodes.Add(format, new UPC5());
						break;
					case BarcodeFormats.UPCE:
						_Barcodes.Add(format, new UPCE());
						break;
					case BarcodeFormats.CPC:
						_Barcodes.Add(format, new CPC());
						break;
					case BarcodeFormats.IntelligentMail:
						_Barcodes.Add(format, new IntelligentMail());
						break;
					case BarcodeFormats.Postnet:
						_Barcodes.Add(format, new PostNet());
						break;
					case BarcodeFormats.RM4SCC:
						_Barcodes.Add(format, new RM4SCC());
						break;
					default:
						break;
				}
			}
			return _Barcodes[format];
		}
	}
}


<|start_filename|>Barcode Writer/DataMatrix/DataMatrixDefinition.cs<|end_filename|>
﻿
namespace Barcodes.Datamatrix
{
    /// <summary>
    /// Holds the defination for DataMatrix layout
    /// </summary>
    internal class DataMatrixDefinition
    {
        /// <summary>
        /// Gets the number of data rows
        /// </summary>
        public int Rows
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the number of data columns
        /// </summary>
        public int Cols
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the number of data regions
        /// </summary>
        public int Regions
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the data word capacity
        /// </summary>
        public int DataWords
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the ECC word count
        /// </summary>
        public int EccWords
        {
            get;
            private set;
        }

        /// <summary>
        /// Initialise a new definition
        /// </summary>
        /// <param name="rows">row count</param>
        /// <param name="cols">column count</param>
        /// <param name="regions">region count</param>
        /// <param name="datawords">data word count</param>
        /// <param name="eccwords">ecc word count</param>
        public DataMatrixDefinition(int rows, int cols, int regions, int datawords, int eccwords)
        {
            Rows = rows;
            Cols = cols;
            Regions = regions;
            DataWords = datawords;
            EccWords = eccwords;
        }
    }
}


<|start_filename|>Barcodes2/Definitions/Single/Code11.cs<|end_filename|>
﻿using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Barcodes2.Definitions.Single
{
	public class Code11 : DefaultDefinition
	{
		private const int LIMIT = 's';

		public Code11()
		{
			//IsChecksumRequired = true;
		}

		protected override Regex GetRegex()
		{
			return new Regex("^[\\d-]+$");
		}

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			PatternSet.Add('0', Pattern.Parse("nb nw nb nw wb"));
			PatternSet.Add('1', Pattern.Parse("wb nw nb nw wb"));
			PatternSet.Add('2', Pattern.Parse("nb ww nb nw wb"));
			PatternSet.Add('3', Pattern.Parse("wb ww nb nw nb"));
			PatternSet.Add('4', Pattern.Parse("nb nw wb nw wb"));
			PatternSet.Add('5', Pattern.Parse("wb nw wb nw nb"));
			PatternSet.Add('6', Pattern.Parse("nb ww wb nw nb"));
			PatternSet.Add('7', Pattern.Parse("nb nw nb ww wb"));
			PatternSet.Add('8', Pattern.Parse("wb nw nb ww nb"));
			PatternSet.Add('9', Pattern.Parse("wb nw nb nw nb"));
			PatternSet.Add('-', Pattern.Parse("nb nw wb nw nb"));
			PatternSet.Add('s', Pattern.Parse("nb nw wb ww nb"));
		}

		public override CodedValueCollection GetCodes(string value)
		{
			value = string.Format("{1}{0}{1}", value, (char)LIMIT);

			return base.GetCodes(value);
		}

		public override string AddChecksum(string value, CodedValueCollection codes)
		{
			codes.RemoveAt(codes.Count - 1);

			value = DoChecksumCalculation(value, 10, codes);

			if (value.Length >= 10)
				value = DoChecksumCalculation(value, 9,codes);

			codes.Add(LIMIT);

			return value;
		}

		protected static string DoChecksumCalculation(string value, int factor, CodedValueCollection codes)
		{
			int tmp = 0;
			int weight = 0;
			for (int i = 0; i < value.Length; i++)
			{
				weight = ((value.Length - i) % factor);
				if (weight == 0)
					weight = factor;
				tmp += ((value[i] == '-' ? 10 : int.Parse(value.Substring(i, 1))) * weight);
			}

			tmp = tmp % 11;
			value += tmp > 9 ? "-" : tmp.ToString();
			if (codes != null)
			{
				if (codes.Last() == LIMIT)
					codes.Insert(codes.Count - 1, tmp > 9 ? '-' : tmp + '0');
				else
					codes.Add(tmp > 9 ? '-' : tmp + '0');
			}

			return value;
		}

		public static string AddSingleCheckDigit(string value)
		{
			return DoChecksumCalculation(value, 10, null);
		}

		public static string AddDoubleCheckDigit(string value)
		{
			var tmp = DoChecksumCalculation(value, 10, null);
			return DoChecksumCalculation(tmp, 9, null);
		}
	}
}


<|start_filename|>Barcodes2/Definitions/DefaultDefinition.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Barcodes2.Definitions
{
	public abstract class DefaultDefinition : IDefinition
	{
		private Regex _pattern;
		private IDictionary<int, Pattern> _patternSet;

		protected IDictionary<int, Pattern> PatternSet
		{
			get
			{
				if (_patternSet == null)
					CreatePatternSet();

				return _patternSet;
			}
			set
			{
				_patternSet = value;
			}
		}

		public bool IsChecksumRequired
		{
			get;
			set;
		}

		protected abstract Regex GetRegex();

		public virtual bool IsDataValid(string value)
		{
			if (_pattern == null)
				_pattern = GetRegex();

			return _pattern.IsMatch(value);
		}

		public virtual CodedValueCollection GetCodes(string value)
		{
			var result = new CodedValueCollection();
			foreach (var item in value)
			{
				result.Add(item);
			}
			return result;
		}

		public virtual string GetDisplayText(string value)
		{
			return value;
		}

		public Pattern GetPattern(int value)
		{
			return PatternSet[value];
		}

		protected abstract void CreatePatternSet();

		public virtual int CalculateWidth(BarcodeSettings settings, CodedValueCollection codes)
		{
			return codes.Sum(x => (PatternSet[x].NarrowCount * settings.NarrowWidth) + (PatternSet[x].WideCount * settings.WideWidth)) + (codes.Count * settings.ModulePadding);
		}

		public virtual string AddChecksum(string value, CodedValueCollection codes)
		{
			throw new NotSupportedException();
		}

		public virtual void TransformSettings(BarcodeSettings settings)
		{ }
	}
}


<|start_filename|>Barcodes2/GS1/GS1Value.cs<|end_filename|>
﻿using System;

namespace Barcodes2.GS1
{
	public class GS1Value
	{
		#region AI Constants

		public const int SSCC18 = 0;
		public const int GTIN = 1;
		public const int NumberofContainersContained = 2;
		public const int BatchNumbers = 10;
		public const int ProductionDate = 11;
		public const int DueDate = 12;
		public const int PackagingDate = 13;
		public const int BestBeforeDate = 15;
		public const int ExpirationDate = 17;
		public const int VariantNumber = 20;
		public const int SerialNumber = 21;
		public const int HIBCCQuantity = 22;
		public const int SecondaryDataField = 22;
		public const int LotNumber = 23;
		public const int AdditionalItemIdentification = 240;
		public const int CustomerPartNumber = 241;
		public const int MadeToOrderVariationNumber = 242;
		public const int SecondSerialNumber = 250;
		public const int ReferenceToSourceEntity = 251;
		public const int GDTI = 253;
		public const int GLNExtension = 254;
		public const int CountofItems = 30;
		public const int ProductNetWeightKg = 310;
		public const int ProductLengthMeters = 311;
		public const int ProductWidthMeters = 312;
		public const int ProductDepthMeters = 313;
		public const int ProductAreaSquareMeters = 314;
		public const int NetVolumeLiters = 315;
		public const int NetVolumeCubicMeters = 316;
		public const int NetWeightPounds = 320;
		public const int ProductLengthInches = 321;
		public const int ProductLengthFeet = 322;
		public const int ProductLengthYards = 323;
		public const int ProductWidthInches = 324;
		public const int ProductWidthFeet = 325;
		public const int ProductWidthYards = 326;
		public const int ProductDepthInches = 327;
		public const int ProductDepthFeet = 328;
		public const int ProductDepthYards = 329;
		public const int LogiticWeightKg = 330;
		public const int ContainerLengthMeters = 331;
		public const int ContainerWidthMeters = 332;
		public const int ContainerDepthMeters = 333;
		public const int ContainerAreaSquareMeters = 334;
		public const int LogisticVolumeLiters = 335;
		public const int LogisticVolumeCubicMeters = 336;
		public const int KilogramsPerSquareMetre = 337;
		public const int LogisticWeightPounds = 340;
		public const int ContainerLengthInches = 341;
		public const int ContainerLengthFeet = 342;
		public const int ContainerLengthYards = 343;
		public const int ContainerWidthInches = 344;
		public const int ContainerWidthFeet = 345;
		public const int ContainerWidthYards = 346;
		public const int ContainerDepthInches = 347;
		public const int ContainerDepthFeet = 348;
		public const int ContainerDepthYards = 349;
		public const int ProductAreaSquareInches = 350;
		public const int ProductAreaSquareFeet = 351;
		public const int ProductAreaSquareYards = 352;
		public const int ContainerAreaSquareInches = 353;
		public const int ContainerAreaSquareFeet = 354;
		public const int ContainerAreaSuqareYards = 355;
		public const int NetWeightTroyOunces = 356;
		public const int NetWeightOunces = 357;
		public const int NetVolumeQuarts = 360;
		public const int NetVolumeGallons = 361;
		public const int LogisticVolumeQuarts = 362;
		public const int LogisticVolumeGallons = 363;
		public const int NetVolumeCubicInches = 364;
		public const int NetVolumeCubicFeet = 365;
		public const int NetVolumeCubicYards = 366;
		public const int LogisticGrossVolumeCubicInches = 367;
		public const int LogisticGrossVolumeCubicFeet = 368;
		public const int LogisticGrossVolumeCubicYards = 369;
		public const int CountofTradeItems = 37;
		public const int AmountPayable = 390;
		public const int AmountPayableISO = 391;
		public const int AmountPayableArea = 392;
		public const int AmountPayableAreaISO = 393;
		public const int CustomerPurchaseOrderNumber = 400;
		public const int GINC = 401;
		public const int GSIN = 402;
		public const int RoutingCode = 403;
		public const int ShipToLocationCode = 410;
		public const int BillToLocationCode = 411;
		public const int PurchaseFromLocationCode = 412;
		public const int ShipForLocationCode = 413;
		public const int PhysicalLocationId = 414;
		public const int InvoicingPartyLocationCode = 415;
		public const int ShipToPostalCode = 420;
		public const int ShipToPostalCodeISO = 421;
		public const int CountryofOrigin = 422;
		public const int CountryOfInitialProcessing = 423;
		public const int CountryOfProcessing = 424;
		public const int CountryOfDisassembly = 425;
		public const int CountryCoveringProcessChain = 426;
		public const int NATOStockNumber = 7001;
		public const int UNCutClassification = 7002;
		public const int ExpirationDateTime = 7003;
		public const int ActivePotency = 7004;
		public const int RollProducts = 8001;
		public const int CellularMobileID = 8002;
		public const int GRAI = 8003;
		public const int GIAI = 8004;
		public const int PricePerUnit = 8005;
		public const int ComponentId = 8006;
		public const int IBAN = 8007;
		public const int ProductionDateTime = 8008;
		public const int GSRN = 8018;
		public const int PaymentSlipReference = 8020;
		public const int CouponExtendedCode = 8100;
		public const int CouponExtendedCodeEndofOffer = 8101;
		public const int CouponExtendedCode0 = 8102;
		public const int CouponCodeIDNorthAmerica = 8110;
		public const int TradingPartners = 90;
		public const int InternalCompanyCodes1 = 91;
		public const int InternalCompanyCodes2 = 92;
		public const int InternalCompanyCodes3 = 93;
		public const int InternalCompanyCodes4 = 94;
		public const int InternalCompanyCodes5 = 95;
		public const int InternalCompanyCoeds6 = 96;
		public const int InternalCompanyCodes7 = 97;
		public const int InternalCompanyCodes8 = 98;
		public const int InternalCompanyCodes9 = 99;

		#endregion

		public int ApplicationIdentifier
		{
			get;
			private set;
		}

		public string Value
		{
			get;
			private set;
		}

		private GS1Value(int applicationIdentifier)
		{
			ApplicationIdentifier = applicationIdentifier;
		}

		private bool Validate(string value)
		{
			string pattern;

			switch (ApplicationIdentifier)
			{
				case SSCC18:
				case ComponentId:
				case GSRN:
					pattern = "^\\d{18}$";
					break;
				case GTIN:
				case NumberofContainersContained:
					pattern = "^\\d{14}$";
					break;
				case BatchNumbers:
				case SerialNumber:
					pattern = "^[a-z0-9]{1,20}$";
					break;
				case ProductionDate:
				case DueDate:
				case PackagingDate:
				case BestBeforeDate:
				case ExpirationDate:
					pattern = "^\\d{2}(0[1-9]|1[0-2])([0-2]\\d|3[01])$";
					break;
				case VariantNumber:
				case CouponExtendedCode0:
					pattern = "^\\d{2}$";
					break;
				case SecondaryDataField:
					pattern = "^[a-z0-9]{1,29}$";
					break;
				case AdditionalItemIdentification:
				case CustomerPartNumber:
				case SecondSerialNumber:
				case ReferenceToSourceEntity:
				case CustomerPurchaseOrderNumber:
				case GINC:
				case RoutingCode:
				case UNCutClassification:
				case GIAI:
				case IBAN:
				case CouponCodeIDNorthAmerica:
				case TradingPartners:
				case InternalCompanyCodes1:
				case InternalCompanyCodes2:
				case InternalCompanyCodes3:
				case InternalCompanyCodes4:
				case InternalCompanyCodes5:
				case InternalCompanyCoeds6:
				case InternalCompanyCodes7:
				case InternalCompanyCodes8:
				case InternalCompanyCodes9:
					pattern = "^[a-z0-9]{1,30}$";
					break;
				case MadeToOrderVariationNumber:
					pattern = "^\\d{1,6}";
					break;
				case GDTI:
					pattern = "^\\d{14,30}$";
					break;
				case GLNExtension:
					pattern = "^[a-z0-9]{1,20}$";
					break;
				case CountofItems:
				case CountofTradeItems:
					pattern = "^\\d{1,8}$";
					break;
				case ProductNetWeightKg:
				case ProductLengthMeters:
				case ProductWidthMeters:
				case ProductDepthMeters:
				case ProductAreaSquareMeters:
				case NetVolumeLiters:
				case NetVolumeCubicMeters:
				case NetWeightPounds:
				case ProductLengthInches:
				case ProductLengthFeet:
				case ProductLengthYards:
				case ProductWidthInches:
				case ProductWidthFeet:
				case ProductWidthYards:
				case ProductDepthInches:
				case ProductDepthFeet:
				case ProductDepthYards:
				case LogiticWeightKg:
				case ContainerLengthMeters:
				case ContainerWidthMeters:
				case ContainerDepthMeters:
				case ContainerAreaSquareMeters:
				case LogisticVolumeLiters:
				case LogisticVolumeCubicMeters:
				case KilogramsPerSquareMetre:
				case LogisticWeightPounds:
				case ContainerLengthInches:
				case ContainerLengthFeet:
				case ContainerLengthYards:
				case ContainerWidthInches:
				case ContainerWidthFeet:
				case ContainerWidthYards:
				case ContainerDepthInches:
				case ContainerDepthFeet:
				case ContainerDepthYards:
				case ProductAreaSquareInches:
				case ProductAreaSquareFeet:
				case ProductAreaSquareYards:
				case ContainerAreaSquareInches:
				case ContainerAreaSquareFeet:
				case ContainerAreaSuqareYards:
				case NetWeightTroyOunces:
				case NetWeightOunces:
				case NetVolumeQuarts:
				case NetVolumeGallons:
				case LogisticVolumeQuarts:
				case LogisticVolumeGallons:
				case NetVolumeCubicInches:
				case NetVolumeCubicFeet:
				case NetVolumeCubicYards:
				case LogisticGrossVolumeCubicInches:
				case LogisticGrossVolumeCubicFeet:
				case LogisticGrossVolumeCubicYards:
					pattern = "^\\d{7}$";
					break;
				case PricePerUnit:
				case CouponExtendedCode:
					pattern = "^\\d{6}$";
					break;
				case AmountPayable:
				case AmountPayableArea:
					pattern = "^\\d{1,15}$";
					break;
				case AmountPayableISO:
				case AmountPayableAreaISO:
					pattern = "^\\d{4,18}$";
					break;
				case GSIN:
					pattern = "^\\d{17}$";
					break;
				case ShipToLocationCode:
				case BillToLocationCode:
				case PurchaseFromLocationCode:
				case ShipForLocationCode:
				case PhysicalLocationId:
				case InvoicingPartyLocationCode:
				case NATOStockNumber:
					pattern = "^\\d{13}$";
					break;
				case ShipToPostalCode:
					pattern = "^[a-z0-9]{1,20}$";
					break;
				case ShipToPostalCodeISO:
					pattern = "^\\d{3}[a-z0-9]{1,9}$";
					break;
				case CountryofOrigin:
				case CountryOfProcessing:
				case CountryOfDisassembly:
				case CountryCoveringProcessChain:
					pattern = "^\\d{3}$";
					break;
				case CountryOfInitialProcessing:
					pattern = "^\\d{3,15}$";
					break;
				case ExpirationDateTime:
					pattern = "^\\d{10}$";
					break;
				case ActivePotency:
					pattern = "^\\d{1,4}$";
					break;
				case RollProducts:
					pattern = "^\\d{14}$";
					break;
				case CellularMobileID:
					pattern = "^[a-z0-9]{1,20}$";
					break;
				case GRAI:
					pattern = "^\\d{14}[a-z0-9]{1,16}$";
					break;
				case ProductionDateTime:
					pattern = "^\\d{8,12}$";
					break;
				case PaymentSlipReference:
					pattern = "^[a-z0-9]{1,25}$";
					break;
				case CouponExtendedCodeEndofOffer:
					pattern = "^\\d{10}$";
					break;
				default:
					throw new NotSupportedException("Unsupported AI code [" + ApplicationIdentifier.ToString() + "].");
			}

			if (System.Text.RegularExpressions.Regex.IsMatch(value, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
				return true;

			throw new ApplicationException("The value does not meet the specification for the Application Identifier.");
		}

		public static GS1Value Create(int applicationIdentifier, string value)
		{
			var g = new GS1Value(applicationIdentifier);
			if (!g.Validate(value))
				return null;

			g.Value = value;
			return g;
		}

		public static GS1Value Create(int applicationIdentifier, int value)
		{
			return Create(applicationIdentifier, value.ToString());
		}

		public static GS1Value Create(int applicationIdentifier, decimal value, int precision)
		{
			string tmp = (value * (decimal)Math.Pow(10, precision)).ToString();

			if (precision < 0 || precision > 6)
				throw new ArgumentOutOfRangeException("precision", "Decimal precision must be between 0 and 6.");

			return Create(applicationIdentifier, precision.ToString() + tmp);
		}

		public static GS1Value Create(int applicationIdentifier, DateTime value)
		{
			return Create(applicationIdentifier, value, false);
		}

		public static GS1Value Create(int applicationIdentifier, DateTime value, bool ignoreDay)
		{
			string tmp;
			if (ignoreDay)
				tmp = value.ToString("yyMM00");
			else
				tmp = value.ToString("yyMMdd");

			return Create(applicationIdentifier, tmp);
		}
	}
}


<|start_filename|>Barcodes2/DataMatrix/EncoderFormat.cs<|end_filename|>
﻿namespace Barcodes2.DataMatrix
{
	/// <summary>
	/// Encoding formats supported by DataMatrix
	/// </summary>
	public enum EncoderFormat
	{
		Auto,
		AsciiLower,
		AsciiExtended,
		AsciiNumber,
		C40,
		TEXT,
		X12,
		EDIFACT,
		Byte
	}
}

<|start_filename|>Barcodes2/GS1/GS1Helper.cs<|end_filename|>
﻿
namespace Barcodes2.GS1
{
    public class GS1Helper
    {
        public int CheckDigitCalculate(CodedValueCollection codes)
        {
            int total = 0;
            bool flip = true;
            for (int i = codes.Count-1; i > 0; i--)
            {
                if (flip)
                    total += codes[i] * 3;
                else
                    total += codes[i];

                flip = !flip;
            }

            total = total % 10;
            return total == 0 ? 0 : 10 - total;
        }

        public string Normalise(string value)
        {
            if (value.Length < 13)
                value = value.PadLeft(13, '0');

            return value;
        }
    }
}


<|start_filename|>Barcode Writer/1D/EAN13.cs<|end_filename|>
﻿using System;

namespace Barcodes
{
    /// <summary>
    /// European Article Number (EAN) 13 digit code
    /// </summary>
    public class EAN13 : EAN
    {
        private readonly int[] _DigitGrouping;

        protected override int[] DigitGrouping
        {
            get { return _DigitGrouping; }
        }

        public EAN13()
            : base()
        {
            _DigitGrouping = new int[] { 1, 6, 6 };
        }

        protected override void Init()
        {
            base.Init();

            AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^\\d{12,13}$");
            AddChecksum += new EventHandler<AddChecksumEventArgs>(EAN13_AddChecksum);
        }

        void EAN13_AddChecksum(object sender, AddChecksumEventArgs e)
        {
            if (e.Codes.Count == 13)
                return;

            int total =0;
            for (int i = 0; i < e.Codes.Count; i++)
            {
                if (i % 2 == 0)
                    total += (e.Codes[i] % 10);
                else
                    total += 3 * (e.Codes[i] % 10);
            }

            total = total % 10;
            e.Codes.Add(total == 0 ? 20 : 30 - total);
            e.Text += (total == 0 ? 0 : 10 - total).ToString();
        }

    }
}


<|start_filename|>Barcodes2/DataMatrix/DataMatrixWriter.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Barcodes2.DataMatrix
{
	public class DataMatrixWriter
	{
		/// <summary>
		/// Switch to C40 encoding
		/// </summary>
		public const char SWITCHC40 = (char)0xE6;
		/// <summary>
		/// Switch to BYTE encoding
		/// </summary>
		public const char SWITCHBYTE = (char)0xE7;
		/// <summary>
		/// ASCII FNC1 value
		/// </summary>
		public const char FNC1 = (char)0xE8;
		/// <summary>
		/// Switch to ANSI X12 encoding
		/// </summary>
		public const char SWITCHX12 = (char)0xEE;
		/// <summary>
		/// Switch to TEXT encoding
		/// </summary>
		public const char SWITCHTEXT = (char)0xEF;
		/// <summary>
		/// Switch to EDIFACT encoding
		/// </summary>
		public const char SWITCHEDIFACT = (char)0xF0;
		public const char EXTENDEDCHANNEL = (char)0xF1;
		/// <summary>
		/// Switch to ASCII. Also indicates end of data
		/// </summary>
		public const char SWITCHASCII = (char)0xFE;
		/// <summary>
		/// Toggle to extended ASCII
		/// </summary>
		public const char TOGGLEEXTASCI = (char)0xEB;
		/// <summary>
		/// Padding value
		/// </summary>
		public const char PADDING = (char)0x81;

		private struct DataItem
		{
			public EncoderFormat Format;
			public byte[] BinaryData;
			public string Data;

			public DataItem(EncoderFormat format, string data)
			{
				Format = format;
				Data = data;
				BinaryData = null;
			}

			public DataItem(EncoderFormat format, byte[] data)
			{
				Format = format;
				BinaryData = data;
				Data = null;
			}
		}

		private IList<DataItem> _data;
		private MemoryStream _output;
		private EncoderFormat _currentFormat;

		public int Length
		{
			get { return _data.Sum(x => x.Data == null ? x.BinaryData.Length : x.Data.Length); }
		}

		public DataMatrixWriter()
		{
			_data = new List<DataItem>();
		}

		public void Write(string value)
		{
			Write(value, EncoderFormat.Auto);
		}

		public void Write(string value, EncoderFormat format)
		{
			if (format == EncoderFormat.Auto)
				format = EncoderFormat.AsciiLower;

			_data.Add(new DataItem(format, value));
		}

		public void Write(byte[] data)
		{
			_data.Add(new DataItem(EncoderFormat.Byte, data));
		}

		public byte[] ToArray(int capacity)
		{
			_currentFormat = EncoderFormat.AsciiLower;
			_output = new MemoryStream();

			for (int i = 0; i < _data.Count; i++)
			{
				var item = _data[i];

				SwitchFormat(item);

				if (i + 1 == _data.Count)
					CheckEnd(capacity);

				switch (item.Format)
				{
					case EncoderFormat.AsciiLower:
						ParseAscii(item.Data);
						break;
					case EncoderFormat.C40:
					case EncoderFormat.TEXT:
					case EncoderFormat.X12:
						ParseC40(item.Data);
						break;
					case EncoderFormat.EDIFACT:
						ParseEdifact(item.Data);
						break;
					case EncoderFormat.Byte:
						ParseBinary(item.BinaryData);
						break;
				}
			}

			if (capacity > -1 && _output.Length > capacity)
				throw new BarcodeException("Data exceeds barcode capacity");

			return _output.ToArray();
		}

		private void CheckEnd(int capacity)
		{
			var item = _data.Last();

			if (item.Format == EncoderFormat.AsciiLower || item.Format == EncoderFormat.Byte)
				return;

			if (item.Format == EncoderFormat.EDIFACT)
			{
				var tmp = item.Data.TrimEnd(SWITCHASCII);
				var remaining = (tmp.Length) % 4;
				if (remaining == 1 || remaining == 2)
				{
					_data.Add(new DataItem(EncoderFormat.AsciiLower, tmp.Substring(tmp.Length - remaining)));

					item.Data = tmp.Remove(tmp.Length - remaining);
					_currentFormat = EncoderFormat.AsciiLower;
				}
				else if (remaining == 0)
					item.Data = tmp;

				return;
			}

			//handle C40 end rules
		}

		private void SwitchFormat(DataItem item)
		{
			if (_currentFormat == item.Format)
				return;

			if (_currentFormat == EncoderFormat.AsciiLower)
			{
				switch (item.Format)
				{
					case EncoderFormat.C40:
						_output.WriteInt(SWITCHC40);
						break;
					case EncoderFormat.TEXT:
						_output.WriteInt(SWITCHTEXT);
						break;
					case EncoderFormat.X12:
						_output.WriteInt(SWITCHX12);
						break;
					case EncoderFormat.EDIFACT:
						_output.WriteInt(SWITCHEDIFACT);
						break;
					case EncoderFormat.Byte:
						_currentFormat = EncoderFormat.AsciiLower;
						break;
					default:
						throw new BarcodeException("Unknown or unsupported encoding format");
				}

				return;
			}

			if (item.Data.Last() != SWITCHASCII)
				item.Data += SWITCHASCII;
			_currentFormat = EncoderFormat.AsciiLower;
			SwitchFormat(item);
		}

		//public DataMatrixWriter()
		//{
		//	_stream = new MemoryStream();
		//	_currentFormat = EncoderFormat.AsciiLower;
		//}

		//public void Write(string value)
		//{
		//	Write(value, EncoderFormat.Auto);
		//}

		//public void Write(string value, EncoderFormat format)
		//{
		//	if (format == EncoderFormat.Auto)
		//		format = EncoderFormat.AsciiLower;

		//	SwitchFormat(format);

		//	switch (format)
		//	{
		//		case EncoderFormat.AsciiLower:
		//			ParseAscii(value);
		//			break;
		//		case EncoderFormat.C40:
		//		case EncoderFormat.TEXT:
		//		case EncoderFormat.X12:
		//			ParseC40(value);
		//			break;
		//		case EncoderFormat.EDIFACT:
		//			ParseEdifact(value);
		//			break;
		//		case EncoderFormat.Byte:
		//		default:
		//			throw new ArgumentException("Unknown or invalid encoding specified");
		//	}
		//}

		public void ParseBinary(byte[] data)
		{
			if (data.Length <= 249)
				_output.WriteInt(data.Length);
			else if (data.Length >= 250 && data.Length <= 1555)
			{
				_output.WriteInt((data.Length / 250) + 249);
				_output.WriteInt(data.Length % 250);
			}

			_output.Write(data, 0, data.Length);
		}

		private void ParseAscii(string value)
		{
			var index = 0;
			while (index < value.Length)
			{
				if (index + 1 < value.Length && char.IsDigit(value[index]) && char.IsDigit(value[index + 1]))
				{
					var tmp = int.Parse(value.Substring(index, 2));
					_output.WriteInt(130 + tmp);
					index += 2;
				}
				else
				{
					var c = value[index];
					if (c >= 0 && c <= 0x7f)
						_output.WriteInt(c + 1);
					else if (c >= 0x80 && c <= 0xff)
					{
						_output.WriteByte(0xeb);
						_output.WriteInt(c - 0x7f);
					}
					else
						throw new ApplicationException("Value not in ASCII character range");

					index++;
				}
			}
		}

		private void ParseEdifact(string value)
		{
			var targetlength = (((value.Length - 1) / 4) + 1) * 3;
			var tmp = 0;
			int sourceIndex = 0, targetIndex = 0;

			while(targetIndex < targetlength)
			{
				tmp = tmp << 6;
				if (sourceIndex < value.Length)
				{
					if (value[sourceIndex] > 62 && value[sourceIndex] < 95)
						tmp += (value[sourceIndex] & 0x3f);
					else
						throw new ApplicationException("Value encountered not supported by EDIFACT encoding");
				}

				if (sourceIndex % 4 == 3)
				{
					_output.WriteInt(tmp / 0x10000);
					_output.WriteInt(tmp / 0x100);
					_output.WriteInt(tmp % 0x100);

					targetIndex += 3;
				}

				sourceIndex++;
			}
		}

		private void ParseC40(string value)
		{
			Action<int, Queue<byte>> lookupvalue = null;
			if (_currentFormat == EncoderFormat.TEXT)
				lookupvalue = LookupText;
			else
				lookupvalue = LookupC40;

			int sourceIndex = 0;
			var buffer = new Queue<byte>();

			while (buffer.Count > 0 || sourceIndex < value.Length)
			{
				if (sourceIndex < value.Length)
				{
					var c = value[sourceIndex];
					if (c >= 0 && c <= 127)
						lookupvalue(c, buffer);
					else if (c >= 128 && c <= 254)
					{
						buffer.Enqueue(1);
						buffer.Enqueue(30);
						lookupvalue(c - 128, buffer);
					}
					else
						throw new ApplicationException("Invalid character cannot be encoded using C40");
				}
				else
					buffer.Enqueue(0);

				if (buffer.Count >= 3)
				{
					var tmp = (buffer.Dequeue() * 1600) + (buffer.Dequeue() * 40) + buffer.Dequeue() + 1;
					_output.WriteInt(tmp / 0x100);
					_output.WriteInt(tmp % 0x100);
				}

				sourceIndex++;
			}
		}

		private void LookupC40(int value, Queue<byte> buffer)
		{
			var offset = 0;
			if (value == ' ')
				offset = 29;
			else if (value >= '0' && value <= '9')
				offset = 44;
			else if (value >= 'A' && value <= 'Z')
				offset = 51;
			else if (value >= 0 && value <= 31)
			{
				buffer.Enqueue(0);
				offset = 0;
			}
			else if (value >= '!' && value <= '/')
			{
				buffer.Enqueue(1);
				offset = 33;
			}
			else if (value >= ':' && value <= '_')
			{
				buffer.Enqueue(1);
				offset = 43;
			}
			else if (value >= '\'' && value <= 127)
			{
				buffer.Enqueue(2);
				offset = 96;
			}

			buffer.Enqueue((byte)(value - offset));
		}

		private void LookupText(int value, Queue<byte> buffer)
		{
			var offset = 0;
			if (value == 32)
				offset = 29;
			else if (value >= '0' && value <= '9')
				offset = 44;
			else if (value >= 'a' && value <= 'z')
				offset = 83;
			else if (value >= 0 && value <= 31)
			{
				buffer.Enqueue(0);
				offset = 0;
			}
			else if (value >= '!' && value <= '/')
			{
				buffer.Enqueue(1);
				offset = 33;
			}
			else if (value >= ':' && value <= '@')
			{
				buffer.Enqueue(1);
				offset = 43;
			}
			else if (value >= '[' && value <= '_')
			{
				buffer.Enqueue(1);
				offset = 69;
			}
			else if (value == '\'')
			{
				buffer.Enqueue(2);
				offset = 96;
			}
			else if (value >= 'A' && value <= 127)
			{
				buffer.Enqueue(2);
				offset = 64;
			}

			buffer.Enqueue((byte)(value - offset));
		}

		public void Clear()
		{
			_output = null;
			_data.Clear();
		}

		//public byte[] ToBytes(int capacity)
		//{
		//	var output = new MemoryStream();
		//	_stream.Position = 0;
		//	var encoding = EncoderFormat.AsciiLower;
		//	_Latches.Add((int)_stream.Length);

		//	foreach (var item in _Latches)
		//	{
		//		switch (encoding)
		//		{
		//			case EncoderFormat.AsciiLower:

		//				break;
		//			case EncoderFormat.C40:
		//				break;
		//			case EncoderFormat.TEXT:
		//				break;
		//			case EncoderFormat.X12:
		//				break;
		//			case EncoderFormat.EDIFACT:
		//				break;
		//			case EncoderFormat.Byte:
		//				break;
		//			default:
		//				break;
		//		}
		//	}

		//	if (capacity > -1 && output.Length > capacity)
		//		throw new BarcodeException("Data exceeds barcode capacity");

		//	return output.ToArray();
		//}

		//private byte[] Compact(int position, EncoderFormat format)
		//{
		//	byte[] result = null;
		//	var count = _stream.Position - _stream.Length;

		//	if (format == EncoderFormat.AsciiLower || format == EncoderFormat.Byte)
		//	{
		//		result = new byte[count];
		//		_stream.Read(result, 0, result.Length);
		//	}
		//	else if (format == EncoderFormat.EDIFACT)
		//	{
		//	}
		//	return result;
		//}


		//private void WriteBytes(int count, EncoderFormat encoding, Stream stream)
		//{
		//	if (encoding == EncoderFormat.AsciiLower || encoding == EncoderFormat.Byte)
		//	{
		//		_stream.CopyTo(stream, count);
		//	}
		//	else if (encoding == EncoderFormat.EDIFACT)
		//	{
		//		var index = 0;
		//		while (index + 4 < count)
		//		{
		//			int tmp = (_stream.ReadByte() * 0x40000) + (_stream.ReadByte() * 0x1000) + (_stream.ReadByte() * 0x40) + _stream.ReadByte();
		//			stream.WriteByte((byte)(tmp / 0x10000));
		//			stream.WriteByte((byte)(tmp / 0x100));
		//			stream.WriteByte((byte)(tmp % 0x100));

		//			index += 4;
		//		}
		//	}
		//	else
		//	{
		//		var index = 0;
		//		while (index + 3 < count)
		//		{
		//			var tmp = (1600 * _stream.ReadByte()) + (40 * _stream.ReadByte()) + _stream.ReadByte() + 1;
		//			stream.WriteByte((byte)(tmp / 256));
		//			stream.WriteByte((byte)(tmp % 256));
		//			index += 3;
		//		}
		//	}
		//}

		//private void WriteEndBytes(int count, EncoderFormat encoding, Stream stream)
		//{
		//	switch (encoding)
		//	{
		//		case EncoderFormat.AsciiLower:
		//			WriteBytes(count, encoding, stream);
		//			break;
		//		case EncoderFormat.C40:
		//		case EncoderFormat.TEXT:
		//			if ((count % 3) == 2)
		//			{
		//				_stream.WriteByte(0);
		//				WriteBytes(count + 1, encoding, stream);
		//			}
		//			else if ((count % 3) == 1)
		//			{
		//				WriteBytes(count - 1, encoding, stream);
		//				//unlatch if space
		//				WriteBytes(1, EncoderFormat.AsciiLower, stream);
		//			}
		//			else
		//				WriteBytes(count, encoding, stream);
		//			break;
		//		case EncoderFormat.X12:
		//			if ((count % 3) == 2)
		//			{
		//				WriteBytes(count - 2, encoding, stream);
		//				//unlatch
		//				WriteBytes(2, EncoderFormat.AsciiLower, stream);
		//			}
		//			else if ((count % 3) == 1)
		//			{
		//				WriteBytes(count - 1, encoding, stream);
		//				WriteBytes(1, EncoderFormat.AsciiLower, stream);
		//			}
		//			else
		//				WriteBytes(count, encoding, stream);
		//			break;
		//		case EncoderFormat.EDIFACT:
		//			if ((count % 4) == 1 || (count % 4) == 2)
		//			{
		//				WriteBytes(count - (count % 4), encoding, stream);
		//				WriteBytes(count % 4, EncoderFormat.AsciiLower, stream);
		//			}
		//			else
		//				WriteBytes(count, encoding, stream);
		//			break;
		//		case EncoderFormat.Byte:
		//			break;
		//		default:
		//			break;
		//	}
		//}

		//private void WriteLatch(EncoderFormat encoding, Stream stream)
		//{
		//	switch (encoding)
		//	{
		//		case EncoderFormat.Auto:
		//			break;
		//		case EncoderFormat.AsciiLower:
		//			break;
		//		case EncoderFormat.AsciiExtended:
		//			break;
		//		case EncoderFormat.AsciiNumber:
		//			break;
		//		case EncoderFormat.C40:
		//			break;
		//		case EncoderFormat.TEXT:
		//			break;
		//		case EncoderFormat.X12:
		//			break;
		//		case EncoderFormat.EDIFACT:
		//			break;
		//		case EncoderFormat.Byte:
		//			break;
		//		default:
		//			break;
		//	}
		//}
	}
}


<|start_filename|>Barcodes2/Services/ILocatorProvider.cs<|end_filename|>
﻿using System;

namespace Barcodes2.Services
{
	public interface ILocatorProvider
	{
		T Get<T>(params object[] arguments);
		object Get(Type type, params object[] arguments);
	}
}


<|start_filename|>Barcode Writer/1D/Code2of5.cs<|end_filename|>
﻿using System.Collections.Generic;

namespace Barcodes
{
    public class Code2of5 : BarcodeBase
    {
        private const int START = 10;
        private const int STOP = 11;

        protected override void Init()
        {
            AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^\\d+");
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();

            PatternSet.Add(0, Pattern.Parse("nb nw nb nw wb nw wb nw nb"));
            PatternSet.Add(1, Pattern.Parse("wb nw nb nw nb nw nb nw wb"));
            PatternSet.Add(2, Pattern.Parse("nb nw wb nw nb nw nb nw wb"));
            PatternSet.Add(3, Pattern.Parse("wb nw wb nw nb nw nb nw nb"));
            PatternSet.Add(4, Pattern.Parse("nb nw nb nw wb nw nb nw wb"));
            PatternSet.Add(5, Pattern.Parse("wb nw wb nw nb nw nb nw nb"));
            PatternSet.Add(6, Pattern.Parse("nb nw wb nw wb nw nb nw nb"));
            PatternSet.Add(7, Pattern.Parse("nb nw nb nw nb nw wb nw wb"));
            PatternSet.Add(8, Pattern.Parse("wb nw nb nw nb nw wb nw nb"));
            PatternSet.Add(9, Pattern.Parse("nb nw wb nw nb nw wb nw nb"));

            PatternSet.Add(START, Pattern.Parse("nb nb nw nb nb nw nb"));
            PatternSet.Add(STOP, Pattern.Parse("nb nb nw nb nw nb nb"));
        }

        public static void AddChecksumEventHandler(object sender, AddChecksumEventArgs e)
        {
            int total = 0;
            bool isEven = true;

            for (int i = e.Codes.Count-2; i < 0; i--)
            {
                total += isEven ? 3 * e.Codes[i] : e.Codes[i];
            }

            total = total % 10;
            total = total == 0 ? 0 : 10 - total;
            e.Codes.Insert(e.Codes.Count - 1, total);
            e.Text += total.ToString();
        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            value = base.ParseText(value, codes);

            for (int i = 0; i < value.Length; i++)
            {
                codes.Add(int.Parse(value.Substring(i, 1)));
            }

            codes.Insert(0, START);
            codes.Add(STOP);

            return value;
        }

        protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
        {
            width += (codes.Count * ((7 * settings.NarrowWidth) + (2 * settings.WideWidth)));
            width += (14 * settings.NarrowWidth);
            return base.OnCalculateWidth(width, settings, codes);
        }
    }
}


<|start_filename|>Barcode Writer/Postal/IntelligentMailHelper.cs<|end_filename|>
﻿using System;

namespace Barcodes
{
    /// <summary>
    /// Inteliigent Mail helper class for the transformation functions
    /// </summary>
    internal class IntelligentMailHelper
    {
        public const int ASCENDER = 'A';
        public const int DESCENDER = 'D';
        public const int FULLBAR = 'F';
        public const int TRACKER = 'T';

        private short[] t5;
        private short[] t2;

        #region Statics

        private static readonly IntelligentMailHelper _Instance;

        public static IntelligentMailHelper Instance
        {
            get { return _Instance; }
        }

        static IntelligentMailHelper()
        {
            _Instance = new IntelligentMailHelper();
        }

        #endregion

        private IntelligentMailHelper()
        {
            t5 = InitialiseNof13Table(5, 1287);
            t2 = InitialiseNof13Table(2, 78);
        }

        /// <summary>
        /// CRC 11 calculation
        /// </summary>
        /// <param name="dataArray">data values to calculate from</param>
        /// <returns>CRC11 value</returns>
        public int CRC11(byte[] dataArray)
        {
            if (dataArray.Length != 13)
                throw new ArgumentException("data must be 13 bytes in length");

            const int GeneratorPolynomial = 0x0F35;
            int FrameCheckSequence = 0x7FF;

            int data = dataArray[12] << 5;
            for (int i = 2; i < 8; i++)
            {
                if (((FrameCheckSequence ^ data) & 0x400) != 0)
                    FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
                else
                    FrameCheckSequence = FrameCheckSequence << 1;

                FrameCheckSequence &= 0x7FF;
                data <<= 1;
            }

            for (int i = 11; i >= 0; i--)
            {
                data = dataArray[i] << 3;
                for (int j = 0; j < 8; j++)
                {
                    if (((FrameCheckSequence ^ data) & 0x400) != 0)
                        FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
                    else
                        FrameCheckSequence = FrameCheckSequence << 1;

                    FrameCheckSequence &= 0x7FF;
                    data <<= 1;
                }
            }

            return FrameCheckSequence;
        }

        /// <summary>
        /// Reverse the bit order in a 16-bit value
        /// </summary>
        /// <param name="input">input to reverse</param>
        /// <returns>reversed value</returns>
        private int Reverse(int input)
        {
            int result = 0;
            for (int i = 0; i < 16; i++)
            {
                result <<= 1;
                result |= (input & 1);
                input >>= 1;
            }

            return result;
        }

        /// <summary>
        /// Initialise the tables for lookup
        /// </summary>
        /// <param name="n">the bit count to use in the table</param>
        /// <param name="length">the length of the table</param>
        /// <returns>lookup table of values</returns>
        private short[] InitialiseNof13Table(int n, int length)
        {
            short[] result = new short[length];
            int lowerIndex = 0;
            int upperIndex = length - 1;
            int bitCount;
            int r;

            for (int i = 0; i < 8192; i++)
            {
                bitCount = 0;
                for (int j = 0; j < 13; j++)
                {
                    if ((i & (1 << j)) != 0)
                        bitCount++;
                }

                if (bitCount != n)
                    continue;

                r = (Reverse(i) >> 3);
                if (r < i)
                    continue;

                if (i == r)
                {
                    result[upperIndex] = (short)i;
                    upperIndex--;
                }
                else
                {
                    result[lowerIndex] = (short)i;
                    lowerIndex++;
                    result[lowerIndex] = (short)r;
                    lowerIndex++;
                }
            }

            if (lowerIndex != upperIndex + 1)
                throw new ApplicationException("Bounds did not meet");

            return result;
        }

        /// <summary>
        /// Incorporate the Frame Check Sequence into the data
        /// </summary>
        /// <param name="fcs">Frame Check Sequence</param>
        /// <param name="data">data to incorporate</param>
        public void IncorporateFCS(int fcs, short[] data)
        {
            if ((fcs & 0x400) != 0)
                data[0] += 659;
            if ((fcs & 0x200) != 0)
                data[9] = (short)(~data[9] & 0x7ff);
            if ((fcs & 0x100) != 0)
                data[9] = (short)(~data[8] & 0x7ff);
            if ((fcs & 0x80) != 0)
                data[9] = (short)(~data[7] & 0x7ff);
            if ((fcs & 0x40) != 0)
                data[9] = (short)(~data[6] & 0x7ff);
            if ((fcs & 0x20) != 0)
                data[9] = (short)(~data[5] & 0x7ff);
            if ((fcs & 0x10) != 0)
                data[9] = (short)(~data[4] & 0x7ff);
            if ((fcs & 0x8) != 0)
                data[9] = (short)(~data[3] & 0x7ff);
            if ((fcs & 0x4) != 0)
                data[9] = (short)(~data[2] & 0x7ff);
            if ((fcs & 0x2) != 0)
                data[9] = (short)(~data[1] & 0x7ff);
            if ((fcs & 0x1) != 0)
                data[9] = (short)(~data[0] & 0x7ff);

        }

        /// <summary>
        /// Encode the routing code
        /// </summary>
        /// <param name="value">routing code value, either 0, 5, 9 or 11 digits long</param>
        /// <returns>encoded number containing the routing code</returns>
        public long ConvertRoutingCode(string value)
        {
            long tmp = 0;
            if (value.Length == 5)
                tmp = long.Parse(value) + 1;
            if (value.Length == 9)
                tmp = long.Parse(value) + 100001;
            if (value.Length == 11)
                tmp = long.Parse(value) + 1000100001;

            return tmp;
        }

        /// <summary>
        /// Encode the routing code and destination code into a byte array
        /// </summary>
        /// <param name="routingcode">Encoded routing code</param>
        /// <param name="value">destination code</param>
        /// <returns>byte array</returns>
        public byte[] ConvertToBytes(long routingcode, string value)
        {
            routingcode = (routingcode * 10) + int.Parse(value.Substring(0, 1));
            routingcode = (routingcode * 5) + int.Parse(value.Substring(1, 1));

            value = routingcode.ToString("d11") + value.Substring(2);

            byte[] result = new byte[13];

            int length = 0, digit = 0;
            for (int i = 0; i < value.Length; i++)
            {
                digit = byte.Parse(value.Substring(i, 1));

                if (length == 0)
                {
                    if (digit != 0)
                    {
                        result[0] = (byte)digit;
                        length = 1;
                    }
                }
                else
                {
                    for (int j = 0; j < length; j++)
                    {
                        digit += result[j] * 10;
                        result[j] = (byte)digit;
                        digit >>= 8;
                    }

                    if (digit != 0)
                    {
                        result[length++] = (byte)digit;
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// Convert the encoded data into code words
        /// </summary>
        /// <param name="data">data to encode</param>
        /// <returns>13 bit code words</returns>
        public short[] ConvertToCodewords(byte[] data)
        {
            ushort[] pairdata = new ushort[7];
            for (int i = 0; i < data.Length - 1; i += 2)
            {
                pairdata[i / 2] = BitConverter.ToUInt16(data, i);
            }
            pairdata[6] = (ushort)(data[12] & 0x3f);

            short[] result = new short[10];
            result[9] = (short)(2 * BaseShift(pairdata, 636));

            for (int i = 8; i > 0; i--)
            {
                result[i] = BaseShift(pairdata, 1365);
            }

            result[0] = (short)pairdata[0];

            return result;
        }

        /// <summary>
        /// Shift the codeword base
        /// </summary>
        /// <param name="data">codewords to convert</param>
        /// <param name="basediv">base to shift to</param>
        /// <returns>shifted code words</returns>
        private short BaseShift(ushort[] data, int basediv)
        {
            int c = 0;
            ushort res;

            for (int i = data.Length - 1; i >= 0; i--)
            {
                c = (c << 16) + data[i];
                res = (ushort)(c / basediv);
                c -= (ushort)res * basediv;

                data[i] = res;
            }

            return (short)c;
        }

        /// <summary>
        /// Check Frame Check Sequence is valid?
        /// </summary>
        /// <param name="fcs">FCS to check</param>
        /// <returns>true if the FCS is greater than 0x400</returns>
        public bool CheckFcs(int fcs)
        {
            return (fcs & 0x400) != 0;
        }

        /// <summary>
        /// Lookup codewords in the tables
        /// </summary>
        /// <param name="data">data to encode</param>
        public void ConvertToCharacters(short[] data)
        {
            for (int i = 0; i < data.Length; i++)
            {
                if (data[i] > 1364)
                    throw new ApplicationException("Invalid value found during conversion.");
                else if (data[i] > 1286)
                    data[i] = t2[data[i] - 1287];
                else
                    data[i] = t5[data[i]];
            }
        }

        /// <summary>
        /// Include the FCS in the data
        /// </summary>
        /// <param name="data">data</param>
        /// <param name="fcs">Frame Check Sequence</param>
        public void IncludeFcs(short[] data, int fcs)
        {

            for (int i = 0; i < data.Length; i++)
            {
                if ((fcs & (1 << i)) != 0)
                    data[i] ^= 0x1fff;
            }
        }

        //ABCDE FGHIJ
        //01234 56789

        //12   11 10 9 8   7 6 5 4   3 2 1 0
        // 1    8  4 2 1   8 4 2 1   8 4 2 1

        /// <summary>
        /// Convert the encoded data into bar patterns
        /// </summary>
        /// <param name="data">data to encode</param>
        /// <returns>bar pattern collection</returns>
        public CodedValueCollection ConvertToBars(short[] data)
        {
            CodedValueCollection result = new CodedValueCollection();

            result.Add(ChooseBar(data[7] & 0x0004, data[4] & 0x0008));
            result.Add(ChooseBar(data[1] & 0x0400, data[0] & 0x0001));
            result.Add(ChooseBar(data[9] & 0x1000, data[2] & 0x0100));
            result.Add(ChooseBar(data[5] & 0x0020, data[6] & 0x0800));
            result.Add(ChooseBar(data[8] & 0x0200, data[3] & 0x0002));
            result.Add(ChooseBar(data[0] & 0x0002, data[5] & 0x1000));
            result.Add(ChooseBar(data[2] & 0x0020, data[1] & 0x0100));
            result.Add(ChooseBar(data[4] & 0x0010, data[9] & 0x0800));
            result.Add(ChooseBar(data[6] & 0x0008, data[8] & 0x0400));
            result.Add(ChooseBar(data[3] & 0x0200, data[7] & 0x0040));

            result.Add(ChooseBar(data[5] & 0x0800, data[1] & 0x0010));
            result.Add(ChooseBar(data[8] & 0x0020, data[2] & 0x1000));
            result.Add(ChooseBar(data[9] & 0x0400, data[0] & 0x0004));
            result.Add(ChooseBar(data[7] & 0x0002, data[6] & 0x0080));
            result.Add(ChooseBar(data[3] & 0x0040, data[4] & 0x0200));
            result.Add(ChooseBar(data[0] & 0x0008, data[8] & 0x0040));
            result.Add(ChooseBar(data[6] & 0x0010, data[2] & 0x0080));
            result.Add(ChooseBar(data[1] & 0x0002, data[9] & 0x0200));
            result.Add(ChooseBar(data[7] & 0x0400, data[5] & 0x0004));
            result.Add(ChooseBar(data[4] & 0x0001, data[3] & 0x0100));

            result.Add(ChooseBar(data[6] & 0x0004, data[0] & 0x0010));
            result.Add(ChooseBar(data[8] & 0x0800, data[1] & 0x0001));
            result.Add(ChooseBar(data[9] & 0x0100, data[3] & 0x1000));
            result.Add(ChooseBar(data[2] & 0x0040, data[7] & 0x0080));
            result.Add(ChooseBar(data[5] & 0x0002, data[4] & 0x0400));
            result.Add(ChooseBar(data[1] & 0x1000, data[6] & 0x0200));
            result.Add(ChooseBar(data[7] & 0x0008, data[8] & 0x0001));
            result.Add(ChooseBar(data[5] & 0x0100, data[9] & 0x0080));
            result.Add(ChooseBar(data[4] & 0x0040, data[2] & 0x0400));
            result.Add(ChooseBar(data[3] & 0x0010, data[0] & 0x0020));

            result.Add(ChooseBar(data[8] & 0x0010, data[5] & 0x0080));
            result.Add(ChooseBar(data[7] & 0x0800, data[1] & 0x0200));
            result.Add(ChooseBar(data[6] & 0x0001, data[9] & 0x0040));
            result.Add(ChooseBar(data[0] & 0x0040, data[4] & 0x0100));
            result.Add(ChooseBar(data[2] & 0x0002, data[3] & 0x0004));
            result.Add(ChooseBar(data[5] & 0x0200, data[8] & 0x1000));
            result.Add(ChooseBar(data[4] & 0x0800, data[6] & 0x0002));
            result.Add(ChooseBar(data[9] & 0x0020, data[7] & 0x0010));
            result.Add(ChooseBar(data[3] & 0x0008, data[1] & 0x0004));
            result.Add(ChooseBar(data[0] & 0x0080, data[2] & 0x0001));

            result.Add(ChooseBar(data[1] & 0x0008, data[4] & 0x0002));
            result.Add(ChooseBar(data[6] & 0x0400, data[3] & 0x0020));
            result.Add(ChooseBar(data[8] & 0x0080, data[9] & 0x0010));
            result.Add(ChooseBar(data[2] & 0x0800, data[5] & 0x0040));
            result.Add(ChooseBar(data[0] & 0x0100, data[7] & 0x1000));
            result.Add(ChooseBar(data[4] & 0x0004, data[8] & 0x0002));
            result.Add(ChooseBar(data[5] & 0x0400, data[3] & 0x0001));
            result.Add(ChooseBar(data[9] & 0x0008, data[0] & 0x0200));
            result.Add(ChooseBar(data[6] & 0x0020, data[2] & 0x0010));
            result.Add(ChooseBar(data[7] & 0x0100, data[1] & 0x0080));

            result.Add(ChooseBar(data[5] & 0x0001, data[4] & 0x0020));
            result.Add(ChooseBar(data[2] & 0x0008, data[0] & 0x0400));
            result.Add(ChooseBar(data[6] & 0x1000, data[9] & 0x0004));
            result.Add(ChooseBar(data[3] & 0x0800, data[1] & 0x0040));
            result.Add(ChooseBar(data[8] & 0x0100, data[7] & 0x0200));
            result.Add(ChooseBar(data[5] & 0x0010, data[0] & 0x0800));
            result.Add(ChooseBar(data[1] & 0x0020, data[2] & 0x0004));
            result.Add(ChooseBar(data[9] & 0x0002, data[4] & 0x1000));
            result.Add(ChooseBar(data[8] & 0x0008, data[6] & 0x0040));
            result.Add(ChooseBar(data[7] & 0x0001, data[3] & 0x0080));

            result.Add(ChooseBar(data[4] & 0x0080, data[7] & 0x0020));
            result.Add(ChooseBar(data[0] & 0x1000, data[1] & 0x0800));
            result.Add(ChooseBar(data[2] & 0x0200, data[9] & 0x0001));
            result.Add(ChooseBar(data[6] & 0x0100, data[5] & 0x0008));
            result.Add(ChooseBar(data[3] & 0x0400, data[8] & 0x0004));

            return result;
        }

        /// <summary>
        /// Converts a pair of values into a 4-state bar
        /// </summary>
        /// <param name="descender">ascender value</param>
        /// <param name="ascender">descender value</param>
        /// <returns>4-state bar value</returns>
        private int ChooseBar(int descender, int ascender)
        {
            if (ascender == 0 && descender == 0)
                return TRACKER;

            if (ascender != 0 && descender != 0)
                return FULLBAR;

            if (ascender != 0)
                return ASCENDER;

            return DESCENDER;
        }
    }
}


<|start_filename|>Barcodes2/Definitions/Single/ExtendedCode3of9.cs<|end_filename|>
﻿using System.Text;

namespace Barcodes2.Definitions.Single
{
	public class ExtendedCode3of9 : Code3of9
	{
		public override CodedValueCollection GetCodes(string value)
		{
			var v = new StringBuilder();
			foreach (char item in value.ToCharArray())
			{
				v.Append(AsciiEncoder.Lookup(item));
			}

			return base.GetCodes(v.ToString());
		}

		public override string GetDisplayText(string value)
		{
			return value;
		}
	}
}


<|start_filename|>Barcodes2/Definitions/EANDefinition.cs<|end_filename|>
﻿using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Barcodes2.Definitions
{
	public abstract class EANDefinition : IDefinition
	{
		protected enum GuardType
		{
			Limit = 31,
			Split = 32
		}
		protected const int TEXTPADDING = 2;

		private Regex _pattern;

		protected IDictionary<int, Pattern> PatternSet
		{
			get;
			set;
		}

		public bool IsChecksumRequired
		{
			get;
			set;
		}

		/// <summary>
		/// List of parity settings used for calculations
		/// </summary>
		protected List<bool[]> Parity;

		/// <summary>
		/// Gets the digits are groupings
		/// </summary>
		protected int[] DigitGrouping
		{
			get;
			set;
		}

		protected abstract Regex GetRegex();

		public virtual bool IsDataValid(string value)
		{
			if (_pattern == null)
				_pattern = GetRegex();

			return _pattern.IsMatch(value);
		}

		public virtual CodedValueCollection GetCodes(string value)
		{
			var codes = new CodedValueCollection();

			for (int i = 0; i < value.Length; i++)
			{
				codes.Add(int.Parse(value.Substring(i, 1)));

			}

			CalculateParity(codes);

			return codes;
		}

		public virtual string GetDisplayText(string value)
		{
			return value;
		}

		public Pattern GetPattern(int value)
		{
			if (PatternSet == null)
				CreatePatternSet();

			return PatternSet[value];
		}

		protected void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			//Odd parity (false)
			PatternSet.Add(0, Pattern.Parse("0 0 0 1 1 0 1"));
			PatternSet.Add(1, Pattern.Parse("0 0 1 1 0 0 1"));
			PatternSet.Add(2, Pattern.Parse("0 0 1 0 0 1 1"));
			PatternSet.Add(3, Pattern.Parse("0 1 1 1 1 0 1"));
			PatternSet.Add(4, Pattern.Parse("0 1 0 0 0 1 1"));
			PatternSet.Add(5, Pattern.Parse("0 1 1 0 0 0 1"));
			PatternSet.Add(6, Pattern.Parse("0 1 0 1 1 1 1"));
			PatternSet.Add(7, Pattern.Parse("0 1 1 1 0 1 1"));
			PatternSet.Add(8, Pattern.Parse("0 1 1 0 1 1 1"));
			PatternSet.Add(9, Pattern.Parse("0 0 0 1 0 1 1"));

			//Even parity (true)
			PatternSet.Add(10, Pattern.Parse("0 1 0 0 1 1 1"));
			PatternSet.Add(11, Pattern.Parse("0 1 1 0 0 1 1"));
			PatternSet.Add(12, Pattern.Parse("0 0 1 1 0 1 1"));
			PatternSet.Add(13, Pattern.Parse("0 1 0 0 0 0 1"));
			PatternSet.Add(14, Pattern.Parse("0 0 1 1 1 0 1"));
			PatternSet.Add(15, Pattern.Parse("0 1 1 1 0 0 1"));
			PatternSet.Add(16, Pattern.Parse("0 0 0 0 1 0 1"));
			PatternSet.Add(17, Pattern.Parse("0 0 1 0 0 0 1"));
			PatternSet.Add(18, Pattern.Parse("0 0 0 1 0 0 1"));
			PatternSet.Add(19, Pattern.Parse("0 0 1 0 1 1 1"));

			//right side
			PatternSet.Add(20, Pattern.Parse("1 1 1 0 0 1 0"));
			PatternSet.Add(21, Pattern.Parse("1 1 0 0 1 1 0"));
			PatternSet.Add(22, Pattern.Parse("1 1 0 1 1 0 0"));
			PatternSet.Add(23, Pattern.Parse("1 0 0 0 0 1 0"));
			PatternSet.Add(24, Pattern.Parse("1 0 1 1 1 0 0"));
			PatternSet.Add(25, Pattern.Parse("1 0 0 1 1 1 0"));
			PatternSet.Add(26, Pattern.Parse("1 0 1 0 0 0 0"));
			PatternSet.Add(27, Pattern.Parse("1 0 0 0 1 0 0"));
			PatternSet.Add(28, Pattern.Parse("1 0 0 1 0 0 0"));
			PatternSet.Add(29, Pattern.Parse("1 1 1 0 1 0 0"));

			PatternSet.Add((int)GuardType.Limit, Pattern.Parse("g1 0 1"));
			PatternSet.Add((int)GuardType.Split, Pattern.Parse("g0 1 0 1 0"));
		}

		protected void CreateParity()
		{
			Parity = new List<bool[]>();
			Parity.Add(new bool[] { false, false, false, false, false, false });
			Parity.Add(new bool[] { false, false, true, false, true, true });
			Parity.Add(new bool[] { false, false, true, true, false, true });
			Parity.Add(new bool[] { false, false, true, true, true, false });
			Parity.Add(new bool[] { false, true, false, false, true, true });
			Parity.Add(new bool[] { false, true, true, false, false, true });
			Parity.Add(new bool[] { false, true, true, true, false, false });
			Parity.Add(new bool[] { false, true, false, true, false, true });
			Parity.Add(new bool[] { false, true, false, true, true, false });
			Parity.Add(new bool[] { false, true, true, false, true, false });
		}

		public int CalculateWidth(BarcodeSettings settings, CodedValueCollection codes)
		{
			return (settings.NarrowWidth * ((codes.Count * 7) + 11)) + (DigitGrouping[0] * 7 * settings.NarrowWidth);
		}

		public abstract string AddChecksum(string value, CodedValueCollection codes);

		public void TransformSettings(BarcodeSettings settings)
		{
			settings.ModulePadding = 0;
		}

		/// <summary>
		/// Calculate parity for given list of codes
		/// </summary>
		/// <param name="codes">list of values</param>
		protected virtual void CalculateParity(CodedValueCollection codes)
		{
			if (Parity == null)
				CreateParity();

			bool[] parity = Parity[codes[0]];

			for (int i = 1; i < codes.Count; i++)
			{
				if (i < 1 + DigitGrouping[1])
				{
					if (parity[i - 1])
						codes[i] += 10;
				}
				else
					codes[i] += 20;
			}
			codes.RemoveAt(0);
		}
	}
}


<|start_filename|>Barcode Writer/1D/EAN.cs<|end_filename|>
﻿#define MEASURE
using System.Collections.Generic;
using System.Drawing;

namespace Barcodes
{
	/// <summary>
	/// Base class for EAN codes
	/// </summary>
	public abstract class EAN : BarcodeBase
	{

		/// <summary>
		/// The type of guard bar to use
		/// </summary>
		protected enum GuardType
		{
			Limit = 31,
			Split = 32
		}
		protected const int TEXTPADDING = 2;

		/// <summary>
		/// List of parity settings used for calculations
		/// </summary>
		protected List<bool[]> Parity;

		/// <summary>
		/// Gets the digits are groupings
		/// </summary>
		protected abstract int[] DigitGrouping
		{
			get;
		}

		/// <summary>
		/// Draws the required guard bar
		/// </summary>
		/// <param name="state">drawing state</param>
		/// <param name="type">type of guard bar to draw</param>
		protected void DrawGuardBar(State state, GuardType type)
		{
			Rectangle[] guardbar = DrawPattern(PatternSet[(int)type], state);
			int offset = (5 * state.Settings.NarrowWidth) / 2;
			foreach (Rectangle bar in guardbar)
			{
				bar.Inflate(0, offset);
				bar.Offset(0, offset);

				state.Canvas.FillRectangle(Brushes.Black, bar);
			}

			state.Left += PatternSet[(int)type].NarrowCount * state.Settings.NarrowWidth;
		}

		protected override void Init()
		{
			DefaultSettings.ModulePadding = 0;

			Parity = new List<bool[]>();
			Parity.Add(new bool[] { false, false, false, false, false, false });
			Parity.Add(new bool[] { false, false, true, false, true, true });
			Parity.Add(new bool[] { false, false, true, true, false, true });
			Parity.Add(new bool[] { false, false, true, true, true, false });
			Parity.Add(new bool[] { false, true, false, false, true, true });
			Parity.Add(new bool[] { false, true, true, false, false, true });
			Parity.Add(new bool[] { false, true, true, true, false, false });
			Parity.Add(new bool[] { false, true, false, true, false, true });
			Parity.Add(new bool[] { false, true, false, true, true, false });
			Parity.Add(new bool[] { false, true, true, false, true, false });
		}

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			//Odd parity (false)
			PatternSet.Add(0, Pattern.Parse("0 0 0 1 1 0 1"));
			PatternSet.Add(1, Pattern.Parse("0 0 1 1 0 0 1"));
			PatternSet.Add(2, Pattern.Parse("0 0 1 0 0 1 1"));
			PatternSet.Add(3, Pattern.Parse("0 1 1 1 1 0 1"));
			PatternSet.Add(4, Pattern.Parse("0 1 0 0 0 1 1"));
			PatternSet.Add(5, Pattern.Parse("0 1 1 0 0 0 1"));
			PatternSet.Add(6, Pattern.Parse("0 1 0 1 1 1 1"));
			PatternSet.Add(7, Pattern.Parse("0 1 1 1 0 1 1"));
			PatternSet.Add(8, Pattern.Parse("0 1 1 0 1 1 1"));
			PatternSet.Add(9, Pattern.Parse("0 0 0 1 0 1 1"));

			//Even parity (true)
			PatternSet.Add(10, Pattern.Parse("0 1 0 0 1 1 1"));
			PatternSet.Add(11, Pattern.Parse("0 1 1 0 0 1 1"));
			PatternSet.Add(12, Pattern.Parse("0 0 1 1 0 1 1"));
			PatternSet.Add(13, Pattern.Parse("0 1 0 0 0 0 1"));
			PatternSet.Add(14, Pattern.Parse("0 0 1 1 1 0 1"));
			PatternSet.Add(15, Pattern.Parse("0 1 1 1 0 0 1"));
			PatternSet.Add(16, Pattern.Parse("0 0 0 0 1 0 1"));
			PatternSet.Add(17, Pattern.Parse("0 0 1 0 0 0 1"));
			PatternSet.Add(18, Pattern.Parse("0 0 0 1 0 0 1"));
			PatternSet.Add(19, Pattern.Parse("0 0 1 0 1 1 1"));

			//right side
			PatternSet.Add(20, Pattern.Parse("1 1 1 0 0 1 0"));
			PatternSet.Add(21, Pattern.Parse("1 1 0 0 1 1 0"));
			PatternSet.Add(22, Pattern.Parse("1 1 0 1 1 0 0"));
			PatternSet.Add(23, Pattern.Parse("1 0 0 0 0 1 0"));
			PatternSet.Add(24, Pattern.Parse("1 0 1 1 1 0 0"));
			PatternSet.Add(25, Pattern.Parse("1 0 0 1 1 1 0"));
			PatternSet.Add(26, Pattern.Parse("1 0 1 0 0 0 0"));
			PatternSet.Add(27, Pattern.Parse("1 0 0 0 1 0 0"));
			PatternSet.Add(28, Pattern.Parse("1 0 0 1 0 0 0"));
			PatternSet.Add(29, Pattern.Parse("1 1 1 0 1 0 0"));

			PatternSet.Add((int)GuardType.Limit, Pattern.Parse("1 0 1"));
			PatternSet.Add((int)GuardType.Split, Pattern.Parse("0 1 0 1 0"));

		}

		/// <summary>
		/// Calculate parity for given list of codes
		/// </summary>
		/// <param name="codes">list of values</param>
		protected virtual void CalculateParity(CodedValueCollection codes)
		{
			bool[] parity = Parity[codes[0]];

			for (int i = 1; i < codes.Count; i++)
			{
				if (i < 1 + DigitGrouping[1])
				{
					if (parity[i - 1])
						codes[i] += 10;
				}
				else
					codes[i] += 20;
			}
			codes.RemoveAt(0);
		}

		protected override void PaintText(State state)
		{
			int y = state.Settings.TopMargin + state.Settings.BarHeight + TEXTPADDING;
			state.Canvas.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

			int x = state.Settings.LeftMargin;

			if (DigitGrouping[0] > 0)
				state.Canvas.DrawString(state.Text.Substring(0, DigitGrouping[0]), state.Settings.Font, Brushes.Black, x, y);

			x += (DigitGrouping[0] * 7 * state.Settings.NarrowWidth);
			x += (PatternSet[(int)GuardType.Limit].NarrowCount * state.Settings.NarrowWidth) + state.Settings.TextPadding;
			state.Canvas.DrawString(state.Text.Substring(DigitGrouping[0], DigitGrouping[1]), state.Settings.Font, Brushes.Black, x, y);

			x += (DigitGrouping[1] * 7 * state.Settings.NarrowWidth);
			x += (PatternSet[(int)GuardType.Split].NarrowCount * state.Settings.NarrowWidth);
			state.Canvas.DrawString(state.Text.Substring(DigitGrouping[0] + DigitGrouping[1], DigitGrouping[2]), state.Settings.Font, Brushes.Black, x, y);
		}

		protected override string ParseText(string value, CodedValueCollection codes)
		{
			value = base.ParseText(value, codes);

			for (int i = 0; i < value.Length; i++)
			{
				codes.Add(int.Parse(value.Substring(i, 1)));

			}

			CalculateParity(codes);

			return value;
		}

		protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
		{
			width += (settings.NarrowWidth * ((codes.Count * 7) + 11)) + (DigitGrouping[0] * 7 * settings.NarrowWidth);

			return base.OnCalculateWidth(width, settings, codes);
		}
		
		protected override void OnBeforeDrawCode(State state)
		{
			state.Left += DigitGrouping[0] * 7 * state.Settings.NarrowWidth;
			DrawGuardBar(state, GuardType.Limit);

			base.OnBeforeDrawCode(state);
		}

		protected override void OnBeforeDrawModule(State state, int index)
		{
			if (index == DigitGrouping[1])
				DrawGuardBar(state, GuardType.Split);
		}

		protected override void OnAfterDrawCode(State state)
		{
			DrawGuardBar(state, GuardType.Limit);
		}
	}
}


<|start_filename|>Barcode Writer/DataMatrix/DataMatrixInitialiser.cs<|end_filename|>
﻿using System;

namespace Barcodes.Datamatrix
{
    /// <summary>
    /// Initialiser for the Reed Solomon calculator
    /// </summary>
    public class DataMatrixInitialiser : IInitialiser
    {
        private DataMatrixDefinition _Definition;

        /// <summary>
        /// Gets the polynomial value
        /// </summary>
        public int G
        {
            get { return 0x012D; }
        }

        /// <summary>
        /// Initialise the class for the specified definition
        /// </summary>
        /// <param name="definition">Definition to use</param>
        internal DataMatrixInitialiser(DataMatrixDefinition definition)
        {
            _Definition = definition;
        }

        /// <summary>
        /// Gets the ECC word count for the given size & error correction level
        /// </summary>
        /// <param name="dataCount">Data word count</param>
        /// <param name="level">Error correction level. For DataMatrix, this must be 1</param>
        /// <returns>the number of ECC words to calculate</returns>
        public int GetECCCount(int dataCount, int level)
        {
            if (level != 1)
                throw new ArgumentOutOfRangeException("DataMatrix supports only one level of error correction.");

            return _Definition.EccWords;
        }
    }
}


<|start_filename|>Barcodes2/BarcodeSettings.cs<|end_filename|>
﻿
namespace Barcodes2
{
	/// <summary>
	/// Barcode settings used to set various aspects of barcode generation
	/// </summary>
	public class BarcodeSettings
	{
		/// <summary>
		/// Gets or sets the height in pixels of the bars
		/// </summary>
		public int BarHeight
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the height of short bar in 4-state codes
		/// </summary>
		public int ShortHeight
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the height of medium height bars in 4-state codes
		/// </summary>
		public int MediumHeight
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the left margin width in pixels
		/// </summary>
		public int LeftMargin
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the right margin width in pixels
		/// </summary>
		public int RightMargin
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the top margin width in pixels
		/// </summary>
		public int TopMargin
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the bottom margin width in pixels
		/// </summary>
		public int BottomMargin
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the width in pixels of wide bars when used
		/// </summary>
		public int WideWidth
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the width in pixels of narrow bars
		/// </summary>
		public int NarrowWidth
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the padding in pixels between modules
		/// </summary>
		public int ModulePadding
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets whether text is displayed with the barcode
		/// </summary>
		public bool IsTextShown
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the padding between the barcode and the text
		/// </summary>
		public int TextPadding
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets whether spacing is added between individual characters in the barcode text
		/// </summary>
		public bool IsTextPadded
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the maximum width of the barcode image
		/// </summary>
		public int MaxWidth
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the maximum height of the barcode image
		/// </summary>
		public int MaxHeight
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the maximum size of the barcode image
		/// </summary>
		public System.Drawing.Size MaxSize
		{
			get { return new System.Drawing.Size(MaxWidth, MaxHeight); }
			set
			{
				MaxHeight = value.Height;
				MaxWidth = value.Width;
			}
		}

		/// <summary>
		/// Gets or sets the font to use for the text
		/// </summary>
		public System.Drawing.Font Font
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets whether the barcode will calculate & add the checksum (where defined)
		/// </summary>
		public bool IsChecksumCalculated
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the image width
		/// </summary>
		public int Width
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the image height
		/// </summary>
		public int Height
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the image size
		/// </summary>
		public System.Drawing.Size Size
		{
			get { return new System.Drawing.Size(Width, Height); }
			set
			{
				Height = value.Height;
				Width = value.Width;
			}
		}

		public float Scale
		{
			get;
			set;
		}

		public BarcodeSettings()
		{
			BarHeight = 80;
			ShortHeight = BarHeight / 3;
			MediumHeight = (BarHeight / 3) * 2;
			LeftMargin = 10;
			RightMargin = 10;
			TopMargin = 10;
			BottomMargin = 10;
			WideWidth = 6;
			NarrowWidth = 2;
			ModulePadding = 2;
			IsTextShown = true;
			TextPadding = 10;
			IsTextPadded = true;
			Font = new System.Drawing.Font(System.Drawing.FontFamily.GenericMonospace, 12);
			IsChecksumCalculated = false;
			Scale = 1.0F;
		}

		/// <summary>
		/// Creates a duplicate of these settings
		/// </summary>
		/// <returns>New seetings object</returns>
		public BarcodeSettings Copy()
		{
			return (BarcodeSettings)this.MemberwiseClone();
		}

		/// <summary>
		/// Scales the barcode. The dimensions & max dimensions are not scaled.
		/// </summary>
		/// <param name="value">scale factor</param>
		//public void Scale(float value)
		//{
		//    if (value == 1)
		//        return;

		//    BarHeight = ScaleValue(value, BarHeight);
		//    ShortHeight = ScaleValue(value, ShortHeight);
		//    MediumHeight = ScaleValue(value, ShortHeight);
		//    LeftMargin = ScaleValue(value, LeftMargin);
		//    RightMargin = ScaleValue(value, RightMargin);
		//    TopMargin = ScaleValue(value, TopMargin);
		//    BottomMargin = ScaleValue(value, BottomMargin);
		//    WideWidth = ScaleValue(value, WideWidth);
		//    NarrowWidth = ScaleValue(value, NarrowWidth);
		//    ModulePadding = ScaleValue(value, ModulePadding);
		//    TextPadding = ScaleValue(value, TextPadding);
		//    Font = new System.Drawing.Font(Font.Name, Font.Size * value);
		//}

		//private int ScaleValue(float scale, int value)
		//{
		//    return (int)Math.Floor((float)value * scale);
		//}
	}
}


<|start_filename|>Barcode Writer/DataMatrix/Encoder.cs<|end_filename|>
﻿using System;
using System.IO;
using System.Text;

namespace Barcodes.Datamatrix
{
    /// <summary>
    /// Encoding formats supported by DataMatrix
    /// </summary>
    public enum EncoderFormat
    {
        Auto,
        AsciiLower,
        AsciiExtended,
        AsciiNumber,
        C40,
        TEXT,
        X12,
        EDIFACT,
        Byte
    }

    /// <summary>
    /// Encodes data using the selected encoding format
    /// </summary>
    public class Encoder
    {
        /// <summary>
        /// Switch to C40 encoding
        /// </summary>
        public const char SWITCHC40 = (char)0xE6;
        /// <summary>
        /// Switch to BYTE encoding
        /// </summary>
        public const char SWITCHBYTE = (char)0xE7;
        /// <summary>
        /// ASCII FNC1 value
        /// </summary>
        public const char FNC1 = (char)0xE8;
        /// <summary>
        /// Switch to ANSI X12 encoding
        /// </summary>
        public const char SWITCHX12 = (char)0xEE;
        /// <summary>
        /// Switch to TEXT encoding
        /// </summary>
        public const char SWITCHTEXT = (char)0xEF;
        /// <summary>
        /// Switch to EDIFACT encoding
        /// </summary>
        public const char SWITCHEDIFACT = (char)0xF0;
        public const char EXTENDEDCHANNEL = (char)0xF1;
        /// <summary>
        /// Switch to ASCII. Also indicates end of data
        /// </summary>
        public const char SWITCHASCII = (char)0xFE;
        /// <summary>
        /// Toggle to extended ASCII
        /// </summary>
        public const char TOGGLEEXTASCI = (char)0xEB;
        /// <summary>
        /// Padding value
        /// </summary>
        public const char PADDING = (char)0x81;

        private string _Value;
        private int _Index;
        private MemoryStream _Stream;
        private EncoderFormat _Format;

        /// <summary>
        /// Gets the current char from the value to encode
        /// </summary>
        private char Current
        {
            get { return _Value[_Index]; }
        }

        /// <summary>
        /// Encodes a value using auto formatting
        /// </summary>
        /// <param name="value">string value to encode</param>
        /// <returns>encoded data as a byte array</returns>
        public byte[] Encode(string value)
        {
            return Encode(value, EncoderFormat.Auto);
        }

        /// <summary>
        /// Encodes a value using the selcted format.
        /// </summary>
        /// <param name="value">string value to encode</param>
        /// <param name="format">encoding format to use</param>
        /// <returns>encoded data as a byte array</returns>
        public byte[] Encode(string value, EncoderFormat format)
        {
            _Stream = new MemoryStream();
            _Value = value;
            _Index = 0;

            if (format == EncoderFormat.Auto)
                _Format = EncoderFormat.AsciiLower;

            while (_Index < _Value.Length)
            {
                switch (_Format)
                {
                    case EncoderFormat.Auto:
                    case EncoderFormat.AsciiLower:
                    case EncoderFormat.AsciiExtended:
                        AsciiEncode();
                        break;
                    case EncoderFormat.AsciiNumber:
                        break;
                    case EncoderFormat.C40:
                        C40Encoder();
                        break;
                    case EncoderFormat.TEXT:
                        TEXTEncoder();
                        break;
                    case EncoderFormat.X12:
                        AnsiX12();
                        break;
                    case EncoderFormat.EDIFACT:
                        EdifactEncoder();
                        break;
                    case EncoderFormat.Byte:
                        ByteEncoder(Encoding.ASCII.GetBytes(_Value.Substring(_Index)));
                        break;
                    default:
                        break;
                }
            }

            return _Stream.ToArray();
        }

        /// <summary>
        /// Encodes binary data using the binary format
        /// </summary>
        /// <param name="data">binary data to encode</param>
        /// <returns>encoded data as a byte array</returns>
        public byte[] Encode(byte[] data)
        {
            _Stream = new MemoryStream();

            ByteEncoder(data);

            return _Stream.ToArray();
        }

        /// <summary>
        /// Starts encoding data using ASCII rules.
        /// </summary>
        private void AsciiEncode()
        {
            while (CanRead() && !IsFormatSwitch(Current))
            {
                if (CanRead(2))
                    NumberEncode();
                else
                {
                    if (Current >= 0 && Current <= 127)
                        _Stream.WriteByte((byte)(Current + 1));
                    else if (Current >= 128 && Current <= 255)
                    {
                        _Stream.WriteByte(0xEB);
                        _Stream.WriteByte((byte)(Current - 127));
                    }
                    else
                        throw new ApplicationException("Character is out of ASCII range.");

                    _Index++;
                }
            }
        }

        /// <summary>
        /// Encodes pairs of digits 00-99
        /// </summary>
        private void NumberEncode()
        {
            int tmp;
            while (CanRead(2) && char.IsDigit(_Value[_Index]) && char.IsDigit(_Value[_Index + 1]))
            {
                tmp = int.Parse(_Value.Substring(_Index, 2));
                _Stream.WriteByte((byte)(tmp + 130));

                _Index += 2;
            }
        }

        /// <summary>
        /// Encodes using C40 rules.
        /// </summary>
        private void C40Encoder()
        {
            _Stream.WriteByte((byte)SWITCHC40);
            DoubleByteEncoder(EncoderFormat.C40);
        }

        /// <summary>
        /// Encodes using TEXT rules
        /// </summary>
        private void TEXTEncoder()
        {
            _Stream.WriteByte((byte)SWITCHTEXT);
            DoubleByteEncoder(EncoderFormat.TEXT);
        }

        /// <summary>
        /// Encodes using ANSI X12 rules
        /// </summary>
        private void AnsiX12()
        {
            _Stream.WriteByte((byte)SWITCHX12);

            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            while (CanRead() && !IsFormatSwitch(Current))
            {
                if (Current == 13)
                    ms.WriteByte(0);
                else if (Current == 42)
                    ms.WriteByte(1);
                else if (Current == 62)
                    ms.WriteByte(2);
                else if (Current == 32)
                    ms.WriteByte(3);
                else if (Current >= 48 && Current <= 57)
                    ms.WriteByte((byte)(Current - 44));
                else if (Current >= 65 && Current <= 90)
                    ms.WriteByte((byte)(Current - 51));
                else
                {
                    _Format = EncoderFormat.AsciiLower;
                    break;
                }

                _Index++;
            }

            Compact(ms);
        }

        /// <summary>
        /// Encodes 3 bytes into 2 bytes. Used by C40 and TEXT
        /// </summary>
        /// <param name="format">format to use</param>
        private void DoubleByteEncoder(EncoderFormat format)
        {
            MemoryStream buffer = new MemoryStream();

            while (CanRead() && !IsFormatSwitch(Current))
            {
                CharToInt(Current, buffer, format);
                _Index++;
            }

            Compact(buffer);
        }

        /// <summary>
        /// Encodes using EDIFACT rules
        /// </summary>
        private void EdifactEncoder()
        {
            MemoryStream buffer = new MemoryStream();

            while (CanRead() && !IsFormatSwitch(Current))
            {
                if (Current >= 64 && Current <= 94)
                    buffer.WriteByte((byte)(Current - 64));
                else if (Current >= 32 && Current <= 63)
                    buffer.WriteByte((byte)Current);
                else
                {
                    buffer.WriteByte(31);
                    _Format = EncoderFormat.AsciiLower;
                    break;
                }
            }

            while (buffer.Length % 4 != 0)
            {
                buffer.WriteByte(0);
            }

            _Stream.WriteByte((byte)SWITCHEDIFACT);

            buffer.Seek(0, SeekOrigin.Begin);
            int tmp = 0;
            while (buffer.Position + 4 < buffer.Length)
            {
                tmp = (tmp * 64) + buffer.ReadByte();

                if (buffer.Position > 1 && buffer.Position % 4 == 1)
                {
                    _Stream.WriteByte((byte)(tmp / 65536));
                    _Stream.WriteByte((byte)((tmp % 65536) / 256));
                    _Stream.WriteByte((byte)(tmp % 256));

                    tmp = 0;
                }
            }
        }

        /// <summary>
        /// Encodes binary data
        /// </summary>
        /// <param name="data"></param>
        private void ByteEncoder(byte[] data)
        {
            _Stream.WriteByte((byte)SWITCHBYTE);

            if (data.Length < 250)
                _Stream.WriteByte((byte)data.Length);
            else
            {
                _Stream.WriteByte((byte)((data.Length / 250) + 249));
                _Stream.WriteByte((byte)(data.Length % 250));
            }

            int tmp;
            for (int i = 0; i < data.Length; i++)
            {
                tmp = ((149 * i) % 250) + 1;
                _Stream.WriteByte((byte)((data[i] + tmp) % 256));
            }
        }

        /// <summary>
        /// Encodes the char using the specified format and writes the result to the stream
        /// </summary>
        /// <param name="value">value to encode</param>
        /// <param name="stream">stream to write to</param>
        /// <param name="format">Encoding format</param>
        private void CharToInt(char value, System.IO.MemoryStream stream, EncoderFormat format)
        {
            //Extended ASCII
            if (value > 127)
            {
                stream.WriteByte(1);
                stream.WriteByte(30);
                value = (char)(value - 128);
            }

            if (value == 32)
            {
                stream.WriteByte(3);
                return;
            }

            if (value >= 48 && value <= 57)
            {
                stream.WriteByte((byte)(value - 44));
                return;
            }
            //Shift set 1
            if (value >= 0 && value <= 31)
            {
                stream.WriteByte(0);
                stream.WriteByte((byte)value);
                return;
            }

            //Shift set 2
            if (value >= 33 && value <= 47)
            {
                stream.WriteByte(1);
                stream.WriteByte((byte)(value - 33));
                return;
            }
            if (value >= 58 && value <= 64)
            {
                stream.WriteByte(1);
                stream.WriteByte((byte)(value - 58 + 15));
                return;
            }
            if (value >= 91 && value <= 95)
            {

                stream.WriteByte(1);
                stream.WriteByte((byte)(value - 91 + 22));
                return;
            }

            if (format == EncoderFormat.C40)
            {
                //Shift 3
                if (value >= 96 && value <= 127)
                {
                    stream.WriteByte(2);
                    stream.WriteByte((byte)(value - 96));
                    return;
                }
            }

            if (format == EncoderFormat.TEXT)
            {
                //Shift 3
                if (value == 96)
                {
                    stream.WriteByte(2);
                    stream.WriteByte((byte)(value - 96));
                    return;
                }
                if (value >= 65 && value <= 90)
                {
                    stream.WriteByte(2);
                    stream.WriteByte((byte)(value - 65 + 1));
                    return;
                }
                if (value >= 123 && value <= 127)
                {
                    stream.WriteByte(2);
                    stream.WriteByte((byte)(value - 123 + 27));
                    return;
                }
            }
        }

        /// <summary>
        /// Compacts 3 bytes into 2.
        /// </summary>
        /// <param name="stream">stream to compact from</param>
        private void Compact(System.IO.MemoryStream stream)
        {
            stream.Seek(0, System.IO.SeekOrigin.Begin);

            int tmp = 0;
            while (stream.Position + 3 < stream.Length)
            {
                tmp = (tmp * 40) + stream.ReadByte();

                if (stream.Position > 1 && stream.Position % 3 == 1)
                {
                    tmp++;
                    _Stream.WriteByte((byte)(tmp / 256));
                    _Stream.WriteByte((byte)(tmp % 256));
                    tmp = 0;
                }
            }

            if (stream.Position != stream.Length)
            {
                _Format = EncoderFormat.AsciiLower;
                _Stream.WriteByte((byte)SWITCHASCII);
                _Index -= (int)(stream.Length - stream.Position - 1);
            }
            else if (CanRead())
                _Stream.WriteByte((byte)SWITCHASCII);

        }

        /// <summary>
        /// Checks the supplied value to see if a switch in encoding rules is needed
        /// </summary>
        /// <param name="value">value to check</param>
        /// <returns>true if a switch is needed. the target format is set as the current format</returns>
        private bool IsFormatSwitch(int value)
        {
            if (_Format != EncoderFormat.AsciiLower && value == SWITCHASCII)
            {
                _Format = EncoderFormat.AsciiLower;
                return true;
            }

            switch (value)
            {
                case SWITCHASCII:
                    return true;
                case SWITCHBYTE:
                    _Format = EncoderFormat.Byte;
                    return true;
                case SWITCHC40:
                    _Format = EncoderFormat.C40;
                    return true;
                case SWITCHEDIFACT:
                    _Format = EncoderFormat.EDIFACT;
                    return true;
                case SWITCHTEXT:
                    _Format = EncoderFormat.TEXT;
                    return true;
                case SWITCHX12:
                    _Format = EncoderFormat.X12;
                    return true;
                default:
                    return false;
            }
        }

        /// <summary>
        /// Returns true if there is a char to read from the input value
        /// </summary>
        /// <returns>true if the index is in range</returns>
        private bool CanRead()
        {
            return CanRead(1);
        }

        /// <summary>
        /// Returns true if there are the specified number of chars to read from the input value
        /// </summary>
        /// <param name="ahead">chars to read ahead</param>
        /// <returns>true if the values are available</returns>
        private bool CanRead(int ahead)
        {
            return _Index + ahead - 1 < _Value.Length;
        }

    }
}


<|start_filename|>Barcodes2/Definitions/Postal/RM4SCC.cs<|end_filename|>
﻿using System.Collections.Generic;
using System.Linq;

namespace Barcodes2.Definitions.Postal
{
	public class RM4SCC : DefaultDefinition
	{
		private const int START = '(';
		private const int STOP = ')';

		public const string DEFAULTDPS1 = "9U";
		public const string DEFAULTDPS2 = "9W";
		public const string DEFAULTDPS3 = "9X";
		public const string DEFAULTDPS4 = "9Y";
		public const string DEFAULTDPS5 = "9Z";

		public RM4SCC()
			: base()
		{
			IsChecksumRequired = true;
		}

		protected override System.Text.RegularExpressions.Regex GetRegex()
		{
			return new System.Text.RegularExpressions.Regex("^[a-z0-9]{5-7}[1-9][ABD-HJLNP-UW-Z]?$");
		}

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			PatternSet.Add('0', Pattern.Parse("ttff"));
			PatternSet.Add('1', Pattern.Parse("tdaf"));
			PatternSet.Add('2', Pattern.Parse("tdfa"));
			PatternSet.Add('3', Pattern.Parse("dtaf"));
			PatternSet.Add('4', Pattern.Parse("dtfa"));
			PatternSet.Add('5', Pattern.Parse("ddaa"));
			PatternSet.Add('6', Pattern.Parse("tadf"));
			PatternSet.Add('7', Pattern.Parse("tftf"));
			PatternSet.Add('8', Pattern.Parse("tfda"));
			PatternSet.Add('9', Pattern.Parse("datf"));

			PatternSet.Add('A', Pattern.Parse("dada"));
			PatternSet.Add('B', Pattern.Parse("dfta"));
			PatternSet.Add('C', Pattern.Parse("tafd"));
			PatternSet.Add('D', Pattern.Parse("tfad"));
			PatternSet.Add('E', Pattern.Parse("tfft"));
			PatternSet.Add('F', Pattern.Parse("daad"));
			PatternSet.Add('G', Pattern.Parse("daft"));
			PatternSet.Add('H', Pattern.Parse("dfat"));
			PatternSet.Add('I', Pattern.Parse("atdf"));
			PatternSet.Add('J', Pattern.Parse("adtf"));
			PatternSet.Add('K', Pattern.Parse("adda"));
			PatternSet.Add('L', Pattern.Parse("fttf"));
			PatternSet.Add('M', Pattern.Parse("ftda"));
			PatternSet.Add('N', Pattern.Parse("fdta"));
			PatternSet.Add('O', Pattern.Parse("atfd"));
			PatternSet.Add('P', Pattern.Parse("adad"));
			PatternSet.Add('Q', Pattern.Parse("adft"));
			PatternSet.Add('R', Pattern.Parse("ftad"));
			PatternSet.Add('S', Pattern.Parse("ftft"));
			PatternSet.Add('T', Pattern.Parse("fdat"));
			PatternSet.Add('U', Pattern.Parse("aadd"));
			PatternSet.Add('V', Pattern.Parse("aftd"));
			PatternSet.Add('W', Pattern.Parse("afdt"));
			PatternSet.Add('X', Pattern.Parse("fatd"));
			PatternSet.Add('Y', Pattern.Parse("fadt"));
			PatternSet.Add('Z', Pattern.Parse("fftt"));

			PatternSet.Add(START, Pattern.Parse("a"));
			PatternSet.Add(STOP, Pattern.Parse("f"));
		}

		public override void TransformSettings(BarcodeSettings settings)
		{
			base.TransformSettings(settings);

			settings.IsTextShown = false;
			settings.ShortHeight = settings.BarHeight / 3;
			settings.MediumHeight = (settings.BarHeight / 3) * 2;
		}

		public override string AddChecksum(string value, CodedValueCollection codes)
		{
			var values = PatternSet.Keys;

			int rowTotal = 0, colTotal = 0, tmp;

			for (int i = 1; i < codes.Count - 1; i++)
			{
				int index = values.First(x => x == codes[i]);
				tmp = (index / 6) + 1;
				rowTotal += (tmp == 6 ? 0 : tmp);

				tmp = (index % 6) + 1;
				colTotal += (tmp == 6 ? 0 : tmp);
			}

			rowTotal = rowTotal % 6;
			rowTotal = rowTotal == 0 ? 6 : rowTotal - 1;

			colTotal = colTotal % 6;
			colTotal = colTotal == 0 ? 5 : colTotal - 1;

			codes.Insert(codes.Count - 1, values.First(x => x == (rowTotal * 6) + colTotal));

			return value;
		}

		public override CodedValueCollection GetCodes(string value)
		{
			var codes = base.GetCodes(value);

			codes.Insert(0, START);
			codes.Add(STOP);

			return codes;		
		}
	}
}


<|start_filename|>Barcode Writer/DataMatrix/DataMatrix.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Drawing;

namespace Barcodes.Datamatrix
{
    public class DataMatrix
    {
        private Encoder _Encoder;
        private bool _IsSquare;
        private System.Drawing.Size _Size;
        private byte[] _Data;
        private Bitmap _Canvas;
        private Barcodes.DataMatrix.OutputSettings _Settings;

        public System.Drawing.Size Size
        {
            get { return _Size; }
            set
            {
                if (!value.IsEmpty && !DataMatrixHelper.Instance.ValidateSize(value))
                    throw new ArgumentException("the size was not valid.");

                _Size = value;
            }
        }

        public bool IsInverted
        {
            get;
            set;
        }

        public EncoderFormat EncodingFormat
        {
            get;
            set;
        }

        public bool IsSquare
        {
            get { return _IsSquare; }
            set { _IsSquare = value; }
        }

        public bool IsRectangle
        {
            get { return !_IsSquare; }
            set { _IsSquare = !value; }
        }

        public DataMatrix()
        {
            IsSquare = true;
            _Encoder = new Encoder();
            Size = System.Drawing.Size.Empty;
            EncodingFormat = EncoderFormat.Auto;
        }

        public DataMatrix(System.Drawing.Size size)
            : this()
        {
            Size = size;
        }

        public System.Drawing.Bitmap Generate(string value)
        {
            _Data = _Encoder.Encode(value, EncodingFormat);

            return Draw();
        }

        public System.Drawing.Bitmap Generate(byte[] data)
        {
            _Data = _Encoder.Encode(data);

            return Draw();
        }

        private System.Drawing.Bitmap Draw()
        {
            DataMatrixDefinition def = ComputeSize();

            ReedSolomon rs = new ReedSolomon(new DataMatrixInitialiser(def));
            _Data = rs.Encode(_Data, 1);

            int row = 0, col = 4;
            bool up = true;
            foreach (byte item in _Data)
            {
                Rectangle[] r = DrawCodeword(item);

                if (row < _Size.Height & col < _Size.Width)
                    Transform(r, row, col);

                if (up)
                {
                    row -= 2;
                    col += 2;

                    up = row >= 0 && col < _Size.Width;
                    if (!up)
                    {
                        row += 3;
                        col += 1;
                    }
                }
                else
                {
                    row += 2;
                    col -= 2;

                    up = row >= _Size.Height && col < 0;

                    if (up)
                    {
                        row += 3;
                        col += 1;
                    }
                }

            }

            throw new NotImplementedException();
        }

        private DataMatrixDefinition ComputeSize()
        {
            int size = _Data.Length;
            if (_Data[_Data.Length - 1] == Encoder.SWITCHASCII)
                size--;

            DataMatrixDefinition def = DataMatrixHelper.Instance.GetDefinitionForSize(size);

            if (def.DataWords < _Data.Length)
            {
                Array.Resize(ref _Data, size);
            }

            return def;
        }

        private Rectangle[] DrawCodeword(byte value)
        {
            int dx = 2, dy = 2;
            byte mask = 1;
            List<Rectangle> result = new List<Rectangle>();

            for (int i = 0; i < 8; i++)
            {
                if ((value & mask) > 0)
                {
                    result.Add(new Rectangle(dx * _Settings.BitSize, dy * _Settings.BitSize, _Settings.BitSize, _Settings.BitSize));
                }
                dx--;
                if (dx < 0)
                {
                    dy--;
                    if (dy == 0)
                        dx = 1;
                    else
                        dx = 2;
                }
                mask <<= 1;
            }

            return result.ToArray();
        }

        private void Transform(Rectangle[] codeword, int row, int col)
        {
            int dx = (row - 3) * _Settings.BitSize;
            int dy = (col - 3) * _Settings.BitSize;

            foreach (Rectangle item in codeword)
            {
                if (item.X + dx < 0)
                    dx += (_Size.Width * _Settings.BitSize);

                if (item.Y + dy < 0)
                    dy += (_Size.Height * _Settings.BitSize);

                item.Offset(dx, dy);
            }
        }
    }
}


<|start_filename|>Barcodes2/Services/DefinitionFactory.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;

namespace Barcodes2.Services
{
	public class DefinitionFactory
	{
		private IDictionary<BarcodeFormats, Definitions.IDefinition> _cache;

		public DefinitionFactory()
		{
			_cache = new Dictionary<BarcodeFormats, Definitions.IDefinition>();
		}

		public virtual Definitions.IDefinition GetDefinition(BarcodeFormats format)
		{
			if (_cache.ContainsKey(format))
				return _cache[format];

			Definitions.IDefinition result = null;
			switch (format)
			{
				case BarcodeFormats.Code3of9:
					result = Locator.Get<Definitions.Single.Code3of9>();
					break;
				case BarcodeFormats.Code128:
					break;
				case BarcodeFormats.Codabar:
					result = Locator.Get<Definitions.Single.Codabar>();
					break;
				case BarcodeFormats.Code11:
					result = Locator.Get<Definitions.Single.Code11>();
					break;
				case BarcodeFormats.Code2of5:
					result = Locator.Get<Definitions.Single.Code2of5>();
					break;
				case BarcodeFormats.Code93:
					result = Locator.Get<Definitions.Single.Code93>();
					break;
				case BarcodeFormats.EAN128:
					break;
				case BarcodeFormats.EAN13:
					result = Locator.Get<Definitions.EAN.EAN13>();
					break;
				case BarcodeFormats.EAN8:
					break;
				case BarcodeFormats.Extended3of9:
					result = Locator.Get<Definitions.Single.ExtendedCode3of9>();
					break;
				case BarcodeFormats.Interleaved2of5:
					result = Locator.Get<Definitions.Single.Interleaved2of5>();
					break;
				case BarcodeFormats.UPC:
					break;
				case BarcodeFormats.UPC2:
					break;
				case BarcodeFormats.UPC5:
					break;
				case BarcodeFormats.UPCE:
					break;
				case BarcodeFormats.CPC:
					result = Locator.Get<Definitions.Postal.CPC>();
					break;
				case BarcodeFormats.IntelligentMail:
					result = Locator.Get<Definitions.Postal.IntelligentMail>();
					break;
				case BarcodeFormats.Postnet:
					result = Locator.Get<Definitions.Postal.Postnet>();
					break;
				case BarcodeFormats.RM4SCC:
					result = Locator.Get<Definitions.Postal.RM4SCC>();
					break;
				default:
					break;
			}

			if (result == null)
				throw new NotImplementedException();

			_cache[format] = result;
			return result;
		}
	}
}


<|start_filename|>Barcode Writer/1D/UPC5.cs<|end_filename|>
﻿using System;
using System.Drawing;

namespace Barcodes
{
	/// <summary>
	/// Universal Product Code (UPC) 5 digit code
	/// </summary>
	public class UPC5 : EAN
	{
		private readonly int[] _digitGrouping;

		protected override int[] DigitGrouping
		{
			get { return _digitGrouping; }
		}

		public UPC5()
			: base()
		{
			_digitGrouping = new int[] { 0, 5, 0 };
		}

		protected override void Init()
		{
			base.Init();

			DefaultSettings.TextPadding = 2;

			PatternSet.Add(33, Pattern.Parse("nb nw nb nb"));
			PatternSet.Add(34, Pattern.Parse("nw nb"));

			Parity.Clear();
			Parity.Add(new bool[] { true, true, false, false, false });
			Parity.Add(new bool[] { true, false, true, false, false });
			Parity.Add(new bool[] { true, false, false, true, false });
			Parity.Add(new bool[] { true, false, false, false, true });
			Parity.Add(new bool[] { false, true, true, false, false });
			Parity.Add(new bool[] { false, false, true, true, false });
			Parity.Add(new bool[] { false, false, false, true, true });
			Parity.Add(new bool[] { false, true, false, true, false });
			Parity.Add(new bool[] { false, true, false, false, true });
			Parity.Add(new bool[] { false, false, true, false, true });

			AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^\\d{5}$");
		}

		protected override void CalculateParity(CodedValueCollection codes)
		{
			int total = (codes[0] + codes[2] + codes[4]) * 3;
			total += (codes[1] + codes[3]) * 9;
			total = (total % 10);

			bool[] parity = Parity[total];

			for (int i = 0; i < codes.Count; i++)
			{
				if (parity[i])
					codes[i] += 10;
			}
		}

		protected override void OnBeforeDrawModule(State state, int index)
		{
			if (index == 1)
				state.Left -= 3 * state.Settings.NarrowWidth;

			if (index > 1 && index % 2 == 1)
				state.Left -= 5 * state.Settings.NarrowWidth;
		}

		protected override void OnBeforeDrawCode(State state)
		{
			state.Top += Convert.ToInt32(state.Settings.Font.GetHeight()) + state.Settings.TextPadding;
		}

		protected override void OnAfterDrawCode(State state)
		{
			//Do nothing
		}

		protected override void PaintText(State state)
		{
			if (!state.Settings.IsTextShown)
				return;

			string text = PadText(state);

			SizeF textSize = state.Canvas.MeasureString(text, state.Settings.Font);
			int x = (int)(state.Canvas.VisibleClipBounds.Width / 2) - ((int)textSize.Width / 2) - 4;
			int y = state.Settings.TopMargin;

			state.Canvas.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
			state.Canvas.DrawString(text, state.Settings.Font, Brushes.Black, x, y);
		}

		protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
		{
			width += ((-23) * settings.NarrowWidth);

			return base.OnCalculateWidth(width, settings, codes);
		}

		protected override string ParseText(string value, CodedValueCollection codes)
		{
			value = base.ParseText(value, codes);

			codes.Insert(4, 34);
			codes.Insert(3, 34);
			codes.Insert(2, 34);
			codes.Insert(1, 34);
			codes.Insert(0, 33);

			return value;
		}

	}
}


<|start_filename|>Barcodes2/RenderState.cs<|end_filename|>
﻿using System.Drawing;

namespace Barcodes2
{
	public class RenderState
	{
		public Point Location
		{
			get;
			set;
		}

		public Pattern CurrentPattern
		{
			get;
			set;
		}

		public int Index
		{
			get;
			set;
		}

		public RenderState()
		{ }

		public RenderState(Point location)
		{
			Location = location;
		}
	}
}


<|start_filename|>Barcodes2/Services/Locator.cs<|end_filename|>
﻿using System;

namespace Barcodes2.Services
{
	public static class Locator
	{
		private static ILocatorProvider _provider;
		private static object _lock;

		public static bool IsLocatorSet
		{
			get { return _provider != null; }
		}

		static Locator()
		{
			_lock = new object();
		}

		public static void SetLocator(ILocatorProvider provider)
		{
			if (IsLocatorSet)
				throw new ApplicationException("The provider is already set");

			lock (_lock)
			{
				if (IsLocatorSet)
					throw new ApplicationException("The provider is already set");

				_provider = provider;
			}
		}

		public static T Get<T>(params object[] arguments)
		{
			if (IsLocatorSet)
				return _provider.Get<T>(arguments);

			if (arguments != null && arguments.Length > 0)
				throw new ArgumentException("arguments are not supported without a locator");

			return Activator.CreateInstance<T>();
		}

		public static object Get(Type type, params object[] arguments)
		{
			if (IsLocatorSet)
				return _provider.Get(type, arguments);

			return Activator.CreateInstance(type, arguments);
		}
	}
}


<|start_filename|>Barcode Writer/Postal/CPC.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;

namespace Barcodes
{
    /// <summary>
    /// Canadian Post Office bar code
    /// </summary>
    public class CPC : BarcodeBase
    {
        private const int ALIGNMENTBAR = 0x100;
        private const int ODDCOUNT = 0x101;

        private Dictionary<string, int> _Lookup;

        protected override void Init()
        {
            DefaultSettings.WideWidth = 4;
            DefaultSettings.IsTextShown = false;
            DefaultSettings.BarHeight = 10;
            DefaultSettings.ModulePadding = 0;

            CreateLookups();

            AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^[A-Z-[DFIOQU]]\\d[A-Z-[DFIOQU]]\\d[A-Z-[DFIOQU]]\\d$");
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();
            for (int i = 0; i < 0x10; i++)
            {
                CreatePattern(i);
            }

            PatternSet.Add(ALIGNMENTBAR, Pattern.Parse("ww nb"));
            PatternSet.Add(ODDCOUNT, Pattern.Parse("ww, nw"));
        }

        /// <summary>
        /// Create the conversion table
        /// </summary>
        private void CreateLookups()
        {
            _Lookup = new Dictionary<string, int>();
            _Lookup.Add("A", 0x07);
            _Lookup.Add("B", 0x0C);
            _Lookup.Add("C", 0x0B);
            _Lookup.Add("E", 0x0D);
            _Lookup.Add("G", 0x09);
            _Lookup.Add("H", 0x08);
            _Lookup.Add("J", 0x06);
            _Lookup.Add("K", 0x03);
            _Lookup.Add("L", 0x02);
            _Lookup.Add("M", 0x04);
            _Lookup.Add("N", 0x16);
            _Lookup.Add("P", 0x1C);
            _Lookup.Add("R", 0x05);
            _Lookup.Add("S", 0x0A);
            _Lookup.Add("T", 0x14);
            _Lookup.Add("V", 0x11);
            _Lookup.Add("W", 0x18);
            _Lookup.Add("X", 0x13);
            _Lookup.Add("Y", 0x0E);
            _Lookup.Add("Z", 0x1A);

            int[] numbers = new int[] { 0xA, 0x2, 0x9, 0x3, 0xB, 0x5, 0x6, 0x7, 0xD, 0xE };
            for (int i = 0; i < numbers.Length; i++)
            {
                _Lookup.Add(i.ToString(), numbers[i]);
            }

            //string alpha = "ABCEGHJKLMNPRSTVWYZ";
            //string tmp;
            //int value;
            //for (int i = 0; i < alpha.Length; i++)
            //{
            //    tmp = alpha.Substring(i, 1);
            //    for (int j = 0; j < numbers.Length; j++)
            //    {
            //        if (_Lookup[tmp] < 0x10)
            //            value = (_Lookup[tmp] * 0x10) + numbers[i];
            //        else if (_Lookup[tmp] == 0x1a)
            //            value = numbers[i] * 0x10;
            //        else
            //            value = (_Lookup[tmp] - 0x10) + (numbers[i] * 0x10);
            //        _Lookup.Add(tmp + i.ToString(), value);
            //    }
            //}

            _Lookup.Add("X0", 0x11);
            _Lookup.Add("X1", 0x14);
            _Lookup.Add("X2", 0x1C);
            _Lookup.Add("X3", 0x41);
            _Lookup.Add("X4", 0x44);
            _Lookup.Add("X5", 0x4C);
            _Lookup.Add("X6", 0xC1);
            _Lookup.Add("X7", 0xC4);
            _Lookup.Add("X8", 0xCC);
            _Lookup.Add("X9", 0x84);
        }

        /// <summary>
        /// Create binary patterns for 0x0 - 0xf
        /// </summary>
        /// <param name="value">value to create pattern for</param>
        private void CreatePattern(int value)
        {
            Elements[] tmp = new Elements[8];
            for (int i = 0; i < 8; i++)
            {
                if (i % 2 == 1)
                    tmp[8-i] = ((value >> (i / 2)) % 2) == 1 ? Elements.NarrowBlack : Elements.NarrowWhite;
                else
                    tmp[i] = Elements.WideWhite;
            }

            PatternSet.Add(value, new Pattern(tmp));
        }
        
        protected override string ParseText(string value, CodedValueCollection codes)
        {
            value = value.Replace(" ", "").ToUpper();
            if (!IsValidData(value))
                throw new ApplicationException("The data was not valid.");

            int tmp = ParsePair(value.Substring(0, 2));
            codes.Add(tmp / 0x10);
            codes.Add(tmp % 0x10);

            tmp = _Lookup[value.Substring(2, 1)];
            codes.Add(tmp / 0x10);
            codes.Add(tmp % 0x10);

            codes.Add(_Lookup[value.Substring(3, 1)]);

            tmp = ParsePair(value.Substring(4, 2));
            codes.Add(tmp / 0x10);
            codes.Add(tmp % 0x10);

            int p = 1;
            foreach (int item in codes)
            {
                p += PatternSet[item].BlackCount;
            }

            codes.Add(ALIGNMENTBAR);
            if (p % 2 == 0)
                codes.Insert(0, ALIGNMENTBAR);
            else
                codes.Insert(0, ODDCOUNT);

            return null;
        }

        /// <summary>
        /// Take a double digit pair & get it's hex value from the conversion table and rules
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private int ParsePair(string value)
        {
            if (_Lookup.ContainsKey(value))
                return _Lookup[value];

            int ho = _Lookup[value.Substring(0, 1)];
            int lo = _Lookup[value.Substring(1,1)];
            if (ho < 0x11)
                return (ho * 0x10) + lo;
            else if (ho == 0x11)
                return 0x10 + lo;
            else if (ho == 0x1a)
                return lo * 0x10;
            else if (ho == 0x16)
                return (lo * 0x10) + 1;
            else
                return (ho - 0x10) + (lo * 0x10);
        }

        protected override void OnBeforeDrawModule(State state, int index)
        {
            //digit 3 uses only 5 bits, so move back 3 bits
            if (index == 3)
                state.Left -= (state.Settings.NarrowWidth + state.Settings.WideWidth) * 3;

            base.OnBeforeDrawModule(state, index);
        }

        protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
        {
            width += (settings.WideWidth + settings.NarrowWidth) * 27; //1+8+5+4+8+1

            return base.OnCalculateWidth(width, settings, codes);
        }
    }
}


<|start_filename|>Barcode Writer/Postal/Postnet.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;

namespace Barcodes
{
	/// <summary>
	/// PostNet barcode used by the US post office
	/// </summary>
	public class PostNet : BarcodeBase
	{
		private const int STARTSTOP = 11;


		protected override void Init()
		{
			DefaultSettings.ModulePadding = 0;
			DefaultSettings.WideWidth = 2 * DefaultSettings.NarrowWidth;
			DefaultSettings.IsTextShown = false;
			DefaultSettings.IsChecksumCalculated = true;

			AllowedCharsPattern = new System.Text.RegularExpressions.Regex(@"^\d{5}((\s|-)?\d{4}((\s|-)?\d{2})?)?$");

			AddChecksum += new EventHandler<AddChecksumEventArgs>(Postnet_AddChecksum);
		}

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			PatternSet.Add(0, Pattern.Parse("aattt"));
			PatternSet.Add(1, Pattern.Parse("tttaa"));
			PatternSet.Add(2, Pattern.Parse("ttata"));
			PatternSet.Add(3, Pattern.Parse("ttaat"));
			PatternSet.Add(4, Pattern.Parse("tatta"));
			PatternSet.Add(5, Pattern.Parse("tatat"));
			PatternSet.Add(6, Pattern.Parse("taatt"));
			PatternSet.Add(7, Pattern.Parse("attta"));
			PatternSet.Add(8, Pattern.Parse("attat"));
			PatternSet.Add(9, Pattern.Parse("atatt"));

			PatternSet.Add(STARTSTOP, Pattern.Parse("a"));
		}

		void Postnet_AddChecksum(object sender, AddChecksumEventArgs e)
		{
			int total = 0;
			for (int i = 1; i < e.Codes.Count - 1; i++)
			{
				total += e.Codes[i];
			}

			total = total % 10;

			e.Codes.Insert(e.Codes.Count - 1, total == 0 ? 0 : 10 - total);
		}

		protected override string ParseText(string value, CodedValueCollection codes)
		{
			value = base.ParseText(value, codes);

			value = value.Replace(" ", "").Replace("-", "");

			for (int i = 0; i < value.Length; i++)
			{
				codes.Add(int.Parse(value.Substring(i, 1)));
			}

			codes.Insert(0, STARTSTOP);
			codes.Add(STARTSTOP);

			return value;
		}

		protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
		{
			width += (((settings.NarrowWidth + settings.WideWidth) * 5) * (codes.Count - 2)) + (2 * settings.NarrowWidth) + settings.WideWidth;

			return base.OnCalculateWidth(width, settings, codes);
		}

		protected override int OnCalculateHeight(int height, BarcodeSettings settings, CodedValueCollection codes)
		{
			height -= (settings.BarHeight - settings.MediumHeight);
			return base.OnCalculateHeight(height, settings, codes);
		}
	}
}


<|start_filename|>Barcodes2/Services/BitmapRenderer.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace Barcodes2.Services
{
	public class BitmapRenderer : IRenderer
	{
		protected Graphics Canvas
		{
			get;
			set;
		}

		protected string DisplayText
		{
			get;
			set;
		}

		protected CodedValueCollection Codes
		{
			get;
			set;
		}

		public virtual string Name
		{
			get { return "BitmapRenderer"; }
		}

		public BarcodeSettings Settings
		{
			get;
			set;
		}

		public Definitions.IDefinition Definition
		{
			get;
			set;
		}

		public object Render(CodedValueCollection codes, string displayText)
		{
			Codes = codes;
			DisplayText = displayText;

			var size = GetDimensions();
			var b = new Bitmap(size.Width, size.Height);
			Canvas = Graphics.FromImage(b);

			var start = new Point(Settings.LeftMargin, Settings.TopMargin);

			Paint(start);

			return b;
		}

		private Size GetDimensions()
		{
			int width = Settings.LeftMargin + Settings.RightMargin + Definition.CalculateWidth(Settings, Codes);
			int height = Settings.TopMargin + Settings.BarHeight + Settings.BottomMargin;

			if (Settings.IsTextShown)
				height += Convert.ToInt32(Settings.Font.GetHeight()) + Settings.TextPadding;

			if (Settings.MaxWidth > 0 && width > Settings.MaxWidth)
				throw new BarcodeSizeException("The barcode width exceeds the maximum allowed width");
			if (Settings.MaxHeight > 0 && height > Settings.MaxHeight)
				throw new BarcodeSizeException("The barcode height exceeds the maximum allowed height");

			if (Settings.Width > 0)
			{
				if (Settings.Width < width)
					throw new BarcodeSizeException("The barcode width is larger than the defined width");

				Settings.LeftMargin = (Settings.Width - width) / 2;
				Settings.RightMargin = Settings.Width - width - Settings.LeftMargin;
				width = Settings.Width;
			}
			if (Settings.Height > 0)
			{
				if (Settings.Height < height)
					throw new BarcodeSizeException("The barcode height is larger than the defined height");
				Settings.TopMargin = (Settings.Height - height) / 2;
				Settings.BottomMargin = Settings.Height - height - Settings.TopMargin;
				height = Settings.Height;
			}

			return new Size((int)Math.Ceiling(width * Settings.Scale), (int)Math.Ceiling(height * Settings.Scale));
		}

		protected void Paint(Point location)
		{
			Canvas.ScaleTransform(Settings.Scale, Settings.Scale);
			Canvas.Clear(Color.White);

			var state = new RenderState(location);
			PreRenderCode(state);

			for (state.Index = 0; state.Index < Codes.Count; state.Index++)
			{
				state.CurrentPattern = Definition.GetPattern(Codes[state.Index]);
				PreRenderModule(state);

				var r = DrawPattern(state.CurrentPattern, state.Location);
				if (r.Length > 0)
					Canvas.FillRectangles(Brushes.Black, r);

				PostRenderModule(state);
			}

			PostRenderCode();
			PaintText();
		}

		protected virtual void PreRenderCode(RenderState state)
		{ }

		protected virtual void PreRenderModule(RenderState state)
		{ }

		private Rectangle[] DrawPattern(Pattern pattern, Point location)
		{
			var rects = new List<Rectangle>();

			bool isGuards = false;
			int offset = (Settings.MediumHeight - Settings.ShortHeight);
			int left = location.X;
			Rectangle rect;
			foreach (var item in pattern.Elements)
			{
				switch (item)
				{
					case Element.WideBlack:
						rect = new Rectangle(left, location.Y, Settings.WideWidth, Settings.BarHeight);
						left += Settings.WideWidth;

						if (isGuards)
							GuardBarTransform(rect);

						rects.Add(rect);
						break;
					case Element.WideWhite:
						left += Settings.WideWidth;
						break;
					case Element.NarrowBlack:
						rect = new Rectangle(left, location.Y, Settings.NarrowWidth, Settings.BarHeight);
						left += Settings.NarrowWidth;

						if (isGuards)
							GuardBarTransform(rect);

						rects.Add(rect);
						break;
					case Element.NarrowWhite:
						left += Settings.NarrowWidth;
						break;
					case Element.Tracker:
						rect = new Rectangle(left, location.Y + offset, Settings.NarrowWidth, Settings.ShortHeight);
						left += Settings.NarrowWidth;
						rects.Add(rect);
						break;
					case Element.Ascender:
						rect = new Rectangle(left, location.Y, Settings.NarrowWidth, Settings.MediumHeight);
						left += Settings.NarrowWidth;
						rects.Add(rect);
						break;
					case Element.Descender:
						rect = new Rectangle(left, location.Y + offset, Settings.NarrowWidth, Settings.MediumHeight);
						left += Settings.NarrowWidth;
						rects.Add(rect);
						break;
					case Element.GuardBar:
						isGuards = true;
						break;
				}
			}

			return rects.ToArray();
		}

		protected virtual void PostRenderModule(RenderState state)
		{
			var location = state.Location;
			location.X += (state.CurrentPattern.WideCount * Settings.WideWidth) + (state.CurrentPattern.NarrowCount * Settings.NarrowWidth) + Settings.ModulePadding;
			state.Location = location;
		}

		protected virtual void PostRenderCode()
		{ }

		protected virtual void GuardBarTransform(Rectangle shape)
		{
			var offset = (5 * Settings.NarrowWidth) / 2;
			shape.Inflate(0, offset);
			shape.Offset(0, offset);
		}

		private void PaintText()
		{
			if (!Settings.IsTextShown)
				return;

			string text = PadText();

			SizeF textSize = Canvas.MeasureString(text, Settings.Font);
			int x = (int)(Canvas.VisibleClipBounds.Width / 2) - ((int)textSize.Width / 2);
			int y = Settings.TopMargin + Settings.BarHeight + Settings.TextPadding;

			Canvas.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
			Canvas.DrawString(text, Settings.Font, Brushes.Black, x, y);
		}

		private string PadText()
		{
			if (!Settings.IsTextPadded)
				return DisplayText;


			var sb = new StringBuilder();
			//sb.Append(" ");
			foreach (char item in DisplayText)
			{
				sb.AppendFormat("{0} ", item);
			}
			return sb.ToString();
		}

		private int GetEndPoint(Rectangle[] pattern)
		{
			var r = pattern.Last();
			return r.X + r.Width;
		}
	}
}


<|start_filename|>Barcodes2/BarcodeSizeException.cs<|end_filename|>
﻿using System;

namespace Barcodes2
{
	public class BarcodeSizeException : BarcodeException
	{
		public BarcodeSizeException()
			: base()
		{ }

		public BarcodeSizeException(string message)
			: base(message)
		{ }

		public BarcodeSizeException(string message, Exception innerException)
			: base(message, innerException)
		{ }
	}
}


<|start_filename|>Barcodes2/CoefficientsCollection.cs<|end_filename|>
﻿
namespace Barcodes2
{
    /// <summary>
    /// Stores coefficients used by the Reed Solomon function
    /// </summary>
    internal class CoefficientsCollection : System.Collections.ObjectModel.KeyedCollection<int, byte[]>
    {
        protected override int GetKeyForItem(byte[] item)
        {
            return item.Length;
        }
    }
}


<|start_filename|>Barcodes2/Services/DebugRenderer.cs<|end_filename|>
﻿
using System.Drawing;
namespace Barcodes2.Services
{
	public class DebugRenderer : BitmapRenderer
	{
		public bool ShowMeasure
		{
			get;
			set;
		}

		public bool ShowModuleShading
		{
			get;
			set;
		}

		protected bool IsGrey
		{
			get;
			set;
		}

		public DebugRenderer()
		{
			ShowMeasure = true;
			ShowModuleShading = true;
		}

		protected virtual void AddMeasure()
		{
			int left = 0;
			bool alt = true;

			while (left < Canvas.VisibleClipBounds.Width)
			{
				if (alt)
					Canvas.FillRectangle(Brushes.Gainsboro, left, 0, 1, Settings.TopMargin);
				left++;
				alt = !alt;
			}
		}

		protected override void PreRenderCode(RenderState state)
		{
			if (ShowMeasure)
				AddMeasure();
			IsGrey = true;

			base.PreRenderCode(state);
		}

		protected override void PreRenderModule(RenderState state)
		{
			base.PreRenderModule(state);

			if (!ShowModuleShading)
				return;

			if (IsGrey)
			{
				Canvas.FillRectangle(Brushes.Gray, state.Location.X, Settings.TopMargin, (state.CurrentPattern.WideCount * Settings.WideWidth) + (state.CurrentPattern.NarrowCount * Settings.NarrowWidth), Canvas.VisibleClipBounds.Height);
			}
			IsGrey = !IsGrey;

		}
	}
}


<|start_filename|>WebControls/UI/Barcode.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;

namespace Barcodes.Web.UI
{
	public class Barcode : WebControl
	{
		public string Data
		{
			get;
			set;
		}

		public BarcodeFormats Format
		{
			get;
			set;
		}

		public System.Drawing.Size ImageSize
		{
			get;
			set;
		}

		public float Scale
		{
			get;
			set;
		}

		public int TopMargin
		{
			get;
			set;
		}

		public int BottomMargin
		{
			get;
			set;
		}

		public int LeftMargin
		{
			get;
			set;
		}

		public int RightMargin
		{
			get;
			set;
		}

		protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)
		{
			Image img = new Image();
			img.CssClass = this.CssClass;

			img.ImageUrl = RequestSettings.UrlBuilder(Data, Format, new System.Web.Routing.RouteValueDictionary(null));

			img.RenderControl(writer);
		}
	}
}


<|start_filename|>Barcode Writer/GS1/GS1Helper.cs<|end_filename|>
﻿
namespace Barcodes.GS1
{
    public class GS1Helper
    {
        public int CheckDigitCalculate(AddChecksumEventArgs e)
        {
            int total = 0;
            bool flip = true;
            for (int i = e.Codes.Count-1; i > 0; i--)
            {
                if (flip)
                    total += e.Codes[i] * 3;
                else
                    total += e.Codes[i];

                flip = !flip;
            }

            total = total % 10;
            return total == 0 ? 0 : 10 - total;
        }

        public string Normalise(string value)
        {
            if (value.Length < 13)
                value = value.PadLeft(13, '0');

            return value;
        }
    }
}


<|start_filename|>Barcodes2/Definitions/EAN/EAN13.cs<|end_filename|>
﻿
namespace Barcodes2.Definitions.EAN
{
	public class EAN13 : EANDefinition
	{
		public EAN13()
		{
			DigitGrouping = new int[] { 1, 6, 6 };
			IsChecksumRequired = true;
		}

		protected override System.Text.RegularExpressions.Regex GetRegex()
		{
			return new System.Text.RegularExpressions.Regex("^\\d{12,13}$");
		}

		public override string AddChecksum(string value, CodedValueCollection codes)
		{
			if (codes.Count == 13)
				return value;

			int total = 0;
			for (int i = 0; i < codes.Count; i++)
			{
				if (i % 2 == 0)
					total += (codes[i] % 10);
				else
					total += 3 * (codes[i] % 10);
			}

			total = total % 10;
			codes.Add(total == 0 ? 20 : 30 - total);
			
			return value + (total == 0 ? 0 : 10 - total).ToString();
		}

		public override CodedValueCollection GetCodes(string value)
		{
			var codes = base.GetCodes(value);

			codes.Insert(6, (int)GuardType.Split);
			codes.Insert(0, (int)GuardType.Limit);
			codes.Add((int)GuardType.Limit);

			return codes;
		}
	}
}


<|start_filename|>Barcode Writer/1D/Interleaved2of5.cs<|end_filename|>
using System;
using System.Collections.Generic;
using System.Text;

namespace Barcodes
{
    public class Interleaved2of5 : BarcodeBase
    {
        private const int STARTMARKER = 101;
        private const int ENDMARKER = 102;

        protected override void Init()
        {
            DefaultSettings.ModulePadding = 0;

            AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^(\\d\\d)+$");
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();

            MakePatterns();

            PatternSet.Add(STARTMARKER, Pattern.Parse("nb nw nb nw"));
            PatternSet.Add(ENDMARKER, Pattern.Parse("wb nw nb"));
        }

        private void MakePatterns()
        {
            string[] widths = { "nnwwn", "wnnnw", "nwnnw", "wwnnn", "nnwnw", "wnwnn", "nwwnn", "nnnww", "wnnwn", "nwnwn" };

            StringBuilder pattern = new StringBuilder();
            for (int i = 0; i < 100; i++)
            {
                pattern.Clear();

                for (int j = 0; j < 5; j++)
                {
                    pattern.Append(widths[i / 10][j]);
                    pattern.Append("b ");
                    pattern.Append(widths[i % 10][j]);
                    pattern.Append("w ");
                }

                pattern.Remove(pattern.Length - 1, 1);

                PatternSet.Add(i, Pattern.Parse(pattern.ToString()));
            }
        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            if (!IsValidData(value))
                throw new ApplicationException();

            codes.Add(STARTMARKER);

            for (int i = 0; i < value.Length; i+=2)
            {
                codes.Add(int.Parse(value.Substring(i, 2)));
            }

            codes.Add(ENDMARKER);

            return value;
        }

        protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
        {
            width += (((4 * settings.WideWidth) + (6 * settings.NarrowWidth)) * codes.Count) + (6 * settings.NarrowWidth) + settings.WideWidth;

            return base.OnCalculateWidth(width, settings, codes);
        }
    }
}


<|start_filename|>Barcodes2/Definitions/IDefinition.cs<|end_filename|>
﻿
namespace Barcodes2.Definitions
{
	public interface IDefinition
	{
		bool IsChecksumRequired { get; set; }
		bool IsDataValid(string value);
		CodedValueCollection GetCodes(string value);
		string GetDisplayText(string value);
		Pattern GetPattern(int value);
		int CalculateWidth(BarcodeSettings settings, CodedValueCollection codes);
		string AddChecksum(string value, CodedValueCollection codes);
		void TransformSettings(BarcodeSettings settings);
	}
}


<|start_filename|>Barcode Writer/BarcodeFormats.cs<|end_filename|>
﻿
namespace Barcodes
{
	/// <summary>
	/// Supported barcode formats
	/// </summary>
	public enum BarcodeFormats
	{
		Code3of9,
		Code128,
		Codabar,
		Code11,
		Code2of5,
		Code93,
		EAN128,
		EAN13,
		EAN8,
		Extended3of9,
		Interleaved2of5,
		UPC,
		UPC2,
		UPC5,
		UPCE,
		CPC,
		IntelligentMail,
		Postnet,
		RM4SCC
	}
}


<|start_filename|>Barcode Writer/1D/ExtendedCode3of9.cs<|end_filename|>
﻿using System.Text;

namespace Barcodes
{
    /// <summary>
    /// Extended Code 3 of 9 to support full 128 ASCII chars.
    /// </summary>
    public class ExtendedCode3of9 : Code3of9
    {
        protected override string ParseText(string value, CodedValueCollection codes)
        {
            StringBuilder v = new StringBuilder();
            foreach (char item in value.ToCharArray())
            {
                v.Append(AsciiEncoder.Lookup(item));
            }

            base.ParseText(v.ToString(), codes);

            return value;
        }

    }
}


<|start_filename|>WebControls/RequestSettings.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Barcodes.Web
{
	/// <summary>
	/// Parses and validates request parameters
	/// </summary>
	public class RequestSettings
	{
		public const string MARGINKEY = "m";
		public const string SCALEKEY = "sc";
		public const string SIZEKEY = "sz";
		public const string DATAKEY = "data";
		public const string FORMATKEY = "f";
		public const string BARCODEKEY = "bc";

		/// <summary>
		/// Gets or sets the image size. 0 dimensions means the size is generated automatically
		/// </summary>
		public Size Size
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the left margin pixels
		/// </summary>
		public int LeftMargin
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the top margin pixels
		/// </summary>
		public int TopMargin
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the right margin pixels
		/// </summary>
		public int RightMargin
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the bottom margin pixels
		/// </summary>
		public int BottomMargin
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the scale factor
		/// </summary>
		public float Scale
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the image format
		/// </summary>
		public System.Drawing.Imaging.ImageFormat Format
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the MIME type for the current image format
		/// </summary>
		public string ContentType
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the barcode data
		/// </summary>
		public string Data
		{
			get;
			private set;
		}

		/// <summary>
		/// Gets the barcode format
		/// </summary>
		public BarcodeFormats BarcodeFormat
		{
			get;
			private set;
		}

		/// <summary>
		/// Parses the collection of values for parameters
		/// </summary>
		/// <param name="values">collection of parameters</param>
		public void Parse(System.Collections.Specialized.NameValueCollection values)
		{
			int c = 2;
			if (values[DATAKEY] == null)
				return;

			if (values[BARCODEKEY] == null)
				return;

			if (values[FORMATKEY] != null)
				c++;

			ParseFormat(values[FORMATKEY]);
			ParseType(values[BARCODEKEY]);
			Data = values[DATAKEY];

			Size = ParseSize(values[SIZEKEY]);
			Scale = ParseScale(values[SCALEKEY]);
			ParseMargins(values[MARGINKEY]);
		}

		/// <summary>
		/// Looks for the image format parameter. Sets the default format to PNG
		/// </summary>
		/// <param name="value">image format value</param>
		private void ParseFormat(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				Format = System.Drawing.Imaging.ImageFormat.Png;
				return;
			}

			switch (value.ToLower())
			{
				case "png":
					ContentType = "image/png";
					Format = System.Drawing.Imaging.ImageFormat.Png;
					break;
				case "jpg":
				case"jpeg":
					ContentType = "image/jpeg";
					Format = System.Drawing.Imaging.ImageFormat.Jpeg;
					break;
				case "bmp":
					ContentType = "image/bmp";
					Format = System.Drawing.Imaging.ImageFormat.Bmp;
					break;
				default:
					throw new ArgumentException("The format specified is not recognised.");
			}
		}

		/// <summary>
		/// Looks for size values in the format 'width,height'
		/// </summary>
		/// <param name="value">size parameter</param>
		/// <returns>size; empty if not specifed</returns>
		private Size ParseSize(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return Size.Empty;
			}

			string[] a = value.Split(',');
			if (a.Length != 2)
				return Size.Empty;

			Size result = new Size();
			if (a[0] == "")
				result.Width = 0;
			else
				result.Width = int.Parse(a[0]);

			if (a[1] == "")
				result.Height = 0;
			else
				result.Height = int.Parse(a[1]);

			return result;
		}

		/// <summary>
		/// Looks for a scaling factor, returns 1 if not specified
		/// </summary>
		/// <param name="value">scale parameter</param>
		/// <returns>scale value</returns>
		private float ParseScale(string value)
		{
			if (string.IsNullOrEmpty(value))
				return 1;

			return float.Parse(value);
		}

		/// <summary>
		/// Looks for margins in one of the allowed formats format 'm', 'h,v', 'l,t,r,b'
		/// </summary>
		/// <param name="value">margins parameter</param>
		private void ParseMargins(string value)
		{
			LeftMargin = 0;
			RightMargin = 0;
			TopMargin = 0;
			BottomMargin = 0;

			if (string.IsNullOrEmpty(value))
			{
				return;
			}

			string[] a = value.Split(',');

			if (a.Length == 1)
			{
				LeftMargin = int.Parse(a[0]);
				RightMargin = LeftMargin;
				TopMargin = LeftMargin;
				BottomMargin = LeftMargin;

				return;
			}

			if (a.Length == 2)
			{
				if (a[0] != "")
				{
					LeftMargin = int.Parse(a[0]);
					RightMargin = LeftMargin;
				}

				if (a[1] != "")
				{
					TopMargin = int.Parse(a[1]);
					BottomMargin = TopMargin;
				}

				return;
			}

			if (a.Length != 4)
				throw new ArgumentException("Margin format is incorrect");

			if (a[0] != "")
				LeftMargin = int.Parse(a[0]);
			if (a[1] != "")
				TopMargin = int.Parse(a[1]);
			if (a[2] != "")
				RightMargin = int.Parse(a[2]);
			if (a[3] != "")
				BottomMargin = int.Parse(a[3]);
		}

		/// <summary>
		/// looks for the barcode format parameter
		/// </summary>
		/// <param name="value">barcode format parameter</param>
		private void ParseType(string value)
		{
			if (string.IsNullOrEmpty(value))
				return;

			BarcodeFormats t = (BarcodeFormats)int.Parse(value);
			if (!Enum.IsDefined(typeof(BarcodeFormats), t))
				throw new ArgumentException("The requested barcode format is not supported");

			BarcodeFormat = t;
		}

		internal static string UrlBuilder(string data, BarcodeFormats format, IDictionary<string, object> options)
		{
			StringBuilder result = new StringBuilder();

			result.Append(System.Web.VirtualPathUtility.ToAbsolute(Config.Instance.Url));
			result.AppendFormat("?{0}={1}", RequestSettings.DATAKEY, data);
			result.AppendFormat("&{0}={1:d}", RequestSettings.BARCODEKEY, format);

			if (options.ContainsKey(RequestSettings.FORMATKEY))
				result.AppendFormat("&{0}={1}", RequestSettings.FORMATKEY, options[RequestSettings.FORMATKEY]);

			if (options.ContainsKey("scale"))
				result.AppendFormat("&{0}={1}", RequestSettings.SCALEKEY, options["scale"]);

			string tmp = GetSize(options);
			if (tmp != ",")
				result.AppendFormat("&{0}={1}", RequestSettings.SIZEKEY, tmp);

			tmp = GetMargins(options);
			if (tmp != "")
				result.AppendFormat("&{0}={1}", RequestSettings.MARGINKEY, tmp);

			return result.ToString();
		}

		private static string GetSize(IDictionary<string, object> options)
		{
			string result = "";
			if (options.ContainsKey("width"))
				result = options["width"].ToString();
			result += ",";
			if (options.ContainsKey("height"))
				result += options["height"].ToString();

			return result;
		}

		private static string GetMargins(IDictionary<string, object> options)
		{
			string result = "";

			if (options.ContainsKey("margin"))
				return options["margin"].ToString();

			return result;
		}
	}
}


<|start_filename|>Barcodes2/DataMatrix/LayoutRenderer.cs<|end_filename|>
﻿using System.Collections.Generic;
using System.Drawing;

namespace Barcodes2.DataMatrix
{
	public class LayoutRenderer
	{
		private List<Rectangle> _array;
		private List<int> _locations;
		private int _index;
		private byte[] _data;

		public Size Size
		{
			get;
			set;
		}

		private byte Data
		{
			get { return _data[_index]; }
		}

		private void Module(int row, int col, byte mask)
		{
			if (row < 0)
			{
				row += Size.Height;
				col += 4 - ((Size.Height + 4) % 8);
			}

			if (col < 0)
			{
				col += Size.Width;
				row += 4 - ((Size.Width + 4) % 8);
			}

			_locations.Add(row * Size.Width + col);
			if ((Data & mask) == mask)
				_array.Add(new Rectangle(col, row, 1, 1));
		}
		
		private void Utah(Point location)
		{
			Module(location.Y - 2, location.X - 2, 0x80);
			Module(location.Y - 2, location.X - 1, 0x40);
			Module(location.Y - 1, location.X - 2, 0x20);
			Module(location.Y - 1, location.X - 1, 0x10);
			    Module(location.Y - 1, location.X, 0x08);
			    Module(location.Y, location.X - 2, 0x04);
			    Module(location.Y, location.X - 1, 0x02);
			        Module(location.Y, location.X, 0x01);

			_index++;
		}

		private void Corner1()
		{
			Module(Size.Height - 1, 0, 0x80);
			Module(Size.Height - 1, 1, 0x40);
			Module(Size.Height - 1, 2, 0x20);
			Module(0, Size.Width - 2, 0x10);
			Module(0, Size.Width - 1, 0x08);
			Module(1, Size.Width - 1, 0x04);
			Module(2, Size.Width - 1, 0x02);
			Module(3, Size.Width - 1, 0x01);

			_index++;
		}

		private void Corner2()
		{
			Module(Size.Height - 3, 0, 0x80);
			Module(Size.Height - 2, 0, 0x40);
			Module(Size.Height - 1, 0, 0x20);
			Module(0, Size.Width - 4, 0x10);
			Module(0, Size.Width - 3, 0x08);
			Module(0, Size.Width - 2, 0x04);
			Module(0, Size.Width - 1, 0x02);
			Module(1, Size.Width - 1, 0x01);

			_index++;
		}

		private void Corner3()
		{
			Module(Size.Height - 3, 0, 0x80);
			Module(Size.Height - 2, 0, 0x40);
			Module(Size.Height - 1, 0, 0x20);
			Module(0, Size.Width - 2, 0x10);
			Module(0, Size.Width - 1, 0x08);
			Module(1, Size.Width - 1, 0x04);
			Module(2, Size.Width - 1, 0x02);
			Module(3, Size.Width - 1, 0x01);

			_index++;
		}

		private void Corner4()
		{
			Module(Size.Height - 1, 0, 0x80);
			Module(Size.Height - 1, Size.Width - 1, 0x40);
			Module(0, Size.Width - 3, 0x20);
			Module(0, Size.Width - 2, 0x10);
			Module(0, Size.Width - 1, 0x08);
			Module(1, Size.Width - 3, 0x04);
			Module(1, Size.Width - 2, 0x02);
			Module(1, Size.Width - 1, 0x01);

			_index++;
		}

		public Rectangle[] Render(byte[] data)
		{
			if (Size.Height < 6 || (Size.Height & 0x01) == 1 || Size.Width < 6 || (Size.Width & 0x01) == 1)
				throw new BarcodeException("The dimensions were invalid");

			_array = new List<Rectangle>();
			_locations = new List<int>();
			_index = 0;
			_data = data;
			var location = new Point(0, 4);

			do
			{
				if ((location.Y == Size.Height) && (location.X == 0))
					Corner1();
				if ((location.Y == Size.Height - 2) && (location.X == 0) && (Size.Width % 4 > 0))
					Corner2();
				if ((location.Y == Size.Height - 2) && (location.X == 0) && (Size.Width % 8 == 4))
					Corner3();
				if ((location.Y == Size.Height + 4) && (location.X == 2) && (Size.Width % 8 == 0))
					Corner4();

				do
				{
					if ((location.Y < Size.Height) && (location.X >= 0) && !_locations.Contains(location.Y * Size.Width + location.X))
						Utah(location);
					location.Y -= 2;
					location.X += 2;
				} while ((location.Y >= 0) && (location.X < Size.Width));
				location.Y += 1;
				location.X += 3;

				do
				{
					if ((location.Y >= 0) && (location.X < Size.Width) && !_locations.Contains(location.Y * Size.Width + location.X))
						Utah(location);
					location.Y += 2;
					location.X -= 2;
				} while ((location.Y < Size.Height) && (location.X >= 0));
				location.Y += 3;
				location.X += 1;

			} while ((location.Y < Size.Height) || (location.X < Size.Width));

			if (!_locations.Contains(Size.Height * Size.Width - 1))
			{
				_array.Add(new Rectangle(Size.Width - 1, Size.Height, 1, 1));
				_array.Add(new Rectangle(Size.Width - 2, Size.Height - 1, 1, 1));
			}
			return _array.ToArray();
			//	_array[Size.Height * Size.Width - 1] = _array[Size.Height * _cols - Size.Width - 2] = 1;
		}
	}
}


<|start_filename|>Barcodes2/Definitions/Single/Codabar.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Barcodes2.Definitions.Single
{
	public class Codabar : DefaultDefinition
	{
		public const string LIMITVALUEA = "A";
		public const string LIMITVALUEB = "B";
		public const string LIMITVALUEC = "C";
		public const string LIMITVALUED = "D";

		private const string _Extras = ":/.+abcdent*";

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			PatternSet.Add('0', Pattern.Parse("nb nw nb nw nb ww wb"));
			PatternSet.Add('1', Pattern.Parse("nb nw nb nw wb ww nb"));
			PatternSet.Add('2', Pattern.Parse("nb nw nb ww nb nw wb"));
			PatternSet.Add('3', Pattern.Parse("wb ww nb nw nb nw nb"));
			PatternSet.Add('4', Pattern.Parse("nb nw wb nw nb ww nb"));
			PatternSet.Add('5', Pattern.Parse("wb nw nb nw nb ww nb"));
			PatternSet.Add('6', Pattern.Parse("nb ww nb nw nb nw wb"));
			PatternSet.Add('7', Pattern.Parse("nb ww nb nw wb nw nb"));
			PatternSet.Add('8', Pattern.Parse("nb ww wb nw nb nw nb"));
			PatternSet.Add('9', Pattern.Parse("wb nw nb ww nb nw nb"));

			PatternSet.Add('-', Pattern.Parse("nb nw nb ww wb nw nb"));
			PatternSet.Add('$', Pattern.Parse("nb nw wb ww nb nw nb"));
			PatternSet.Add(':', Pattern.Parse("wb nw nb nw wb nw wb"));
			PatternSet.Add('/', Pattern.Parse("wb nw wb nw nb nw wb"));
			PatternSet.Add('.', Pattern.Parse("wb nw wb nw wb nw nb"));
			PatternSet.Add('+', Pattern.Parse("nb nw wb nw wb nw wb"));

			PatternSet.Add('a', Pattern.Parse("nb nw wb ww nb ww nb"));
			PatternSet.Add('b', Pattern.Parse("nb ww nb ww nb nw wb"));
			PatternSet.Add('c', Pattern.Parse("nb nw nb ww nb ww wb"));
			PatternSet.Add('d', Pattern.Parse("nb nw nb ww wb ww nb"));
			PatternSet.Add('t', Pattern.Parse("nb nw wb ww nb ww nb"));
			PatternSet.Add('n', Pattern.Parse("nb ww nb ww nb nw wb"));
			PatternSet.Add('*', Pattern.Parse("nb nw nb ww nb ww wb"));
			PatternSet.Add('e', Pattern.Parse("nb nw nb ww wb ww nb"));
		}

		protected override Regex GetRegex()
		{
			return new Regex(@"^[atbnc\*de][\d-$:/\.\+]+[atbnc\*de]$", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
		}

		public override CodedValueCollection GetCodes(string value)
		{
			value = value.ToLower();
			value = value.Replace(" ", "");

			return base.GetCodes(value);
		}

		public override string GetDisplayText(string value)
		{
			value = value.ToLower();
			return value.Substring(1, value.Length - 2);
		}

		public override string AddChecksum(string value, CodedValueCollection codes)
		{
			var parsed = value.Replace(" ", "");
			if (!System.Text.RegularExpressions.Regex.IsMatch(parsed, "^\\d+$"))
				throw new ArgumentException("Only numeric values can have a check digit");

			int total = 0;

			for (int i = 0; i < parsed.Length; i++)
			{
				if (i % 2 == 0)
					total += int.Parse(parsed.Substring(i, 1));
				else
				{
					int tmp = int.Parse(parsed.Substring(i, 1)) * 2;
					total += (tmp % 9);
				}
			}

			total = total % 10;

			codes.Insert(codes.Count - 1, total.ToString()[0]);
			return value + total.ToString();
		}

		public override bool IsDataValid(string value)
		{
			value = value.ToLower();
			value = value.Replace(" ", "");

			return base.IsDataValid(value);
		}
	}
}


<|start_filename|>Barcode Writer/1D/EAN8.cs<|end_filename|>
﻿using System;

namespace Barcodes
{
    /// <summary>
    /// European Article Number (EAN) 8 digit code
    /// </summary>
    public class EAN8 : EAN
    {
        private readonly int[] _DigitGrouping;

        protected override int[] DigitGrouping
        {
            get { return _DigitGrouping; }
        }

        public EAN8()
            : base()
        {
            _DigitGrouping = new int[] { 0, 4, 4 };
        }

        protected override void Init()
        {
            base.Init();

            AllowedCharsPattern = new System.Text.RegularExpressions.Regex("^\\d{7,8}$");

            AddChecksum += new EventHandler<AddChecksumEventArgs>(EAN8_AddChecksum);
        }

        void EAN8_AddChecksum(object sender, AddChecksumEventArgs e)
        {
            if (e.Codes.Count == 8)
                return;

            int total=0;
            for (int i = 0; i < e.Codes.Count; i++)
            {
                if (i % 2 == 0)
                    total += e.Codes[i] * 3;
                else
                    total += e.Codes[i];
            }

            total = total % 10;
            e.Codes.Add(total == 0 ? 20 : 30 - total);
            e.Text += (total == 0 ? 0 : 10 - total).ToString();
        }

        protected override void CalculateParity(CodedValueCollection codes)
        {
            for (int i = 4; i < codes.Count; i++)
            {
                codes[i] += 20;
            }
        }
    }
}


<|start_filename|>Barcodes2/Services/IRenderer.cs<|end_filename|>
﻿
namespace Barcodes2.Services
{
	public interface IRenderer
	{
		string Name { get; }
		BarcodeSettings Settings { get; set; }
		Definitions.IDefinition Definition { get; set; }
		object Render(CodedValueCollection codes, string displayText);
	}
}


<|start_filename|>Barcodes2/Definitions/Single/Interleaved2of5.cs<|end_filename|>
﻿using System.Collections.Generic;
using System.Text;

namespace Barcodes2.Definitions.Single
{
	public class Interleaved2of5 : DefaultDefinition
	{
		private const int STARTMARKER = 101;
		private const int ENDMARKER = 102;

		protected override System.Text.RegularExpressions.Regex GetRegex()
		{
			return new System.Text.RegularExpressions.Regex("^(\\d\\d)+$");
		}

		protected override void CreatePatternSet()
		{
			PatternSet = new Dictionary<int, Pattern>();

			MakePatterns();

			PatternSet.Add(STARTMARKER, Pattern.Parse("nb nw nb nw"));
			PatternSet.Add(ENDMARKER, Pattern.Parse("wb nw nb"));
		}

		private void MakePatterns()
		{
			string[] widths = { "nnwwn", "wnnnw", "nwnnw", "wwnnn", "nnwnw", "wnwnn", "nwwnn", "nnnww", "wnnwn", "nwnwn" };

			var pattern = new StringBuilder();
			for (int i = 0; i < 100; i++)
			{
				pattern.Clear();

				for (int j = 0; j < 5; j++)
				{
					pattern.Append(widths[i / 10][j]);
					pattern.Append("b ");
					pattern.Append(widths[i % 10][j]);
					pattern.Append("w ");
				}

				pattern.Remove(pattern.Length - 1, 1);

				PatternSet.Add(i, Pattern.Parse(pattern.ToString()));
			}
		}

		public override CodedValueCollection GetCodes(string value)
		{
			var codes = new CodedValueCollection();

			codes.Add(STARTMARKER);
			for (int i = 0; i < value.Length; i += 2)
			{
				codes.Add(int.Parse(value.Substring(i, 2)));
			}

			codes.Add(ENDMARKER);

			return codes;
		}

		public override int CalculateWidth(BarcodeSettings settings, CodedValueCollection codes)
		{
			return (((4 * settings.WideWidth) + (6 * settings.NarrowWidth)) * (codes.Count - 2)) + (6 * settings.NarrowWidth) + settings.WideWidth;
		}

		public override void TransformSettings(BarcodeSettings settings)
		{
			base.TransformSettings(settings);
			settings.ModulePadding = 0;
		}
	}
}


<|start_filename|>Barcode Writer/Postal/IntelligentMail.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Barcodes
{
    /// <summary>
    /// USPS Intelligent Mail barcode
    /// </summary>
    public class IntelligentMail : BarcodeBase
    {
        protected override void Init()
        {
            DefaultSettings.IsTextShown = false;
            DefaultSettings.BarHeight = 12;
            DefaultSettings.ShortHeight = 4;
            DefaultSettings.MediumHeight = 8;
            DefaultSettings.IsChecksumCalculated = false;
            DefaultSettings.ModulePadding = DefaultSettings.NarrowWidth;
        }

        protected override void CreatePatternSet()
        {
            PatternSet = new Dictionary<int, Pattern>();

            PatternSet.Add(IntelligentMailHelper.ASCENDER, Pattern.Parse("a"));
            PatternSet.Add(IntelligentMailHelper.DESCENDER, Pattern.Parse("d"));
            PatternSet.Add(IntelligentMailHelper.FULLBAR, Pattern.Parse("f"));
            PatternSet.Add(IntelligentMailHelper.TRACKER, Pattern.Parse("t"));
        }

        public override bool IsValidData(string value)
        {
            value = Regex.Replace(value,"[-\\s]","");

            if (!Regex.IsMatch(value, @"^\d[0-4]\d{3}"))
                throw new ApplicationException("The barcode identifier or service type was invalid.");

            if (!Regex.IsMatch(value, @"^\d{5}([0-8]\d{5}\d{9}|9\d{8}\d{6})"))
                throw new ApplicationException("The customer identifer or sequence number were invalid.");

            if (!Regex.IsMatch(value, @"^\d{20}(\d{5}(\d{4}(\d{2})?)?)?$"))
                throw new ApplicationException("The delivery point ZIP code was invalid.");

            return true;
        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            value = base.ParseText(value, codes);
            value = Regex.Replace(value, "[-\\s]", "");

            byte[] data1 = IntelligentMailHelper.Instance.ConvertToBytes(IntelligentMailHelper.Instance.ConvertRoutingCode(value.Substring(20)), value.Substring(0,20));
            int fcs = IntelligentMailHelper.Instance.CRC11(data1);

            short[] data2 = IntelligentMailHelper.Instance.ConvertToCodewords(data1);

            if (IntelligentMailHelper.Instance.CheckFcs(fcs))
                data2[0] += 659;

            IntelligentMailHelper.Instance.ConvertToCharacters(data2);

            IntelligentMailHelper.Instance.IncludeFcs(data2, fcs);

            codes.AddRange(IntelligentMailHelper.Instance.ConvertToBars(data2));

            return null;
        }

        protected override int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
        {
            width = settings.NarrowWidth * (codes.Count - 1);
            return base.OnCalculateWidth(width, settings, codes);
        }
    }
}


<|start_filename|>WebControls/Config.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace Barcodes.Web
{
	/// <summary>
	/// Configuraton class for barcodes
	/// </summary>
	public class Config : ConfigurationSection
	{
		private const string SECTIONNAME = "barcodes";
		private const string IMGURL = "generatorUrl";

		/// <summary>
		/// Gets or sets the image generator path
		/// </summary>
		[ConfigurationProperty(IMGURL, IsRequired = true)]
		public string Url
		{
			get { return (string)this[IMGURL]; }
			set { this[IMGURL] = value; }
		}

		/// <summary>
		/// Gets an instance of this config
		/// </summary>
		public static Config Instance
		{
			get { return (Config)ConfigurationManager.GetSection(SECTIONNAME); }
		}
	}
}


<|start_filename|>WebControls/ImageHandler.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Barcodes.Web
{
	/// <summary>
	/// Barcode image handler
	/// </summary>
	public class ImageHandler : System.Web.IHttpHandler
	{
		private IGeneratorService _Generator;

		public bool IsReusable
		{
			get { return true; }
		}

		public ImageHandler()
			: this(null)
		{ }

		public ImageHandler(IGeneratorService service)
		{
			_Generator = service ?? new GeneratorService();
		}

		/// <summary>
		/// Returns a barcode image
		/// </summary>
		/// <param name="context"></param>
		public void ProcessRequest(System.Web.HttpContext context)
		{
			RequestSettings s = new RequestSettings();
			s.Parse(context.Request.QueryString);

			Stream img = _Generator.GetBarcode(s);

			context.Response.ContentType = s.ContentType;

			const int chunk = 1024;
			byte[] buffer = new byte[chunk];
			int read = img.Read(buffer, 0, chunk);
			while (read == chunk)
			{
				context.Response.OutputStream.Write(buffer, 0, chunk);
				read = img.Read(buffer, 0, chunk);
			}
			context.Response.OutputStream.Write(buffer, 0, read);
		}

	}
}


<|start_filename|>Barcode Writer/1D/UPCE.cs<|end_filename|>
﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Barcodes
{
    /// <summary>
    /// Universal Product Code (UPC) 6 digit code
    /// Also known as UPC-E or zero compressed
    /// </summary>
    public class UPCE : EAN
    {
        private int[] _DigitGrouping;

        protected override int[] DigitGrouping
        {
            get { return _DigitGrouping; }
        }

        public UPCE()
            : base()
        {
            _DigitGrouping = new int[] { 0, 6, 0 };
        }

        protected override void Init()
        {
            base.Init();

            PatternSet.Add(33, Pattern.Parse("0 1 0 1 0 1"));

            Parity.Clear();
            Parity.Add(new bool[] { true, true, true, false, false, false });
            Parity.Add(new bool[] { true, true, false, true, false, false });
            Parity.Add(new bool[] { true, true, false, false, true, false });
            Parity.Add(new bool[] { true, true, false, false, false, true });
            Parity.Add(new bool[] { true, false, true, true, false, false });
            Parity.Add(new bool[] { true, false, false, true, true, false });
            Parity.Add(new bool[] { true, false, false, false, true, true });
            Parity.Add(new bool[] { true, false, true, false, true, false });
            Parity.Add(new bool[] { true, false, true, false, false, true });
            Parity.Add(new bool[] { true, false, false, true, false, true });

            AllowedCharsPattern = new Regex("^([01]\\d{6,7}|\\d{11,12})$");
        }

        protected override string ParseText(string value, CodedValueCollection codes)
        {
            if (value.Length > 7)
            {
                value = FromUpcA(value);
            }

            return base.ParseText(value, codes).Substring(1, 6);
        }

        protected override void CalculateParity(CodedValueCollection codes)
        {
            int checkdigit;
            if (codes.Count == 8)
            {
                checkdigit = codes[7];
                codes.RemoveAt(7);
            }
            else
            {
                checkdigit = CalculateCheckCode(codes);
            }

            bool[] parity = Parity[checkdigit];

            for (int i = 0; i < codes.Count; i++)
            {
                if (parity[i] == (codes[0] == 0))
                    codes[i] += 10;
            }
        }

        protected virtual int CalculateCheckCode(CodedValueCollection codes)
        {
            int ld = codes[6];

            int total = (codes[2] * 3) + codes[1];
            switch (ld)
            {
                case 0:
                case 1:
                case 2:
                    total += (codes[3] * 3) + (codes[5] * 3) + ld + codes[4];
                    break;
                case 3:
                    total += (codes[5] * 3) + codes[3] + codes[4];
                    break;
                case 4:
                    total += (codes[4] * 3) + (codes[5] * 3) + codes[3];
                    break;
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                    total += (codes[4] * 3) + (ld * 3) + codes[3] + codes[4];
                    break;
                default:
                    throw new ApplicationException("Unexpected digit found.");
            }

            total = 10 - (total % 10);
            return total == 10 ? 0 : total;
        }

        protected override void OnBeforeDrawModule(State state, int index)
        {
            //No inter-module behaviour
        }

        protected override void OnAfterDrawCode(State state)
        {
            DrawGuardBar(state, (GuardType)33);
        }

        /// <summary>
        /// Converts this UPC-E to a UPC-A code
        /// </summary>
        /// <param name="value">UPC-E value</param>
        /// <returns>UPC-A compatible string</returns>
        public static string ToUpcA(string value)
        {
            if (!Regex.IsMatch(value, "^[01]\\d{6,7}"))
                throw new ApplicationException("The data was not valid.");

            List<int> codes = new List<int>();
            for (int i = 0; i < value.Length; i++)
            {
                codes.Add(int.Parse(value.Substring(i, 1)));

            }

            StringBuilder result = new StringBuilder();
            result.AppendFormat("0{0}00", value.Substring(0, 2));

            int total = (codes[1] * 3) + codes[0];
            switch (codes[5])
            {
                case 0:
                case 1:
                case 2:
                    total += (codes[2] * 3) + (codes[4] * 3) + codes[5] + codes[3];
                    result.Insert(3, codes[5]);
                    result.Insert(5, "00");
                    result.Append(value.Substring(2, 3));
                    break;
                case 3:
                    total += (codes[4] * 3) + codes[2] + codes[3];
                    result.Insert(3, codes[2]);
                    result.Insert(5, "00");
                    result.AppendFormat("0{0}", value.Substring(3, 2));
                    break;
                case 4:
                    total += (codes[3] * 3) + (codes[4] * 3) + codes[2];
                    result.Insert(3, value.Substring(2, 2));
                    result.Insert(5, 0);
                    result.AppendFormat("00{0}", codes[4]);
                    break;
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                    total += (codes[3] * 3) + (codes[5] * 3) + codes[2] + codes[4];
                    result.Insert(3, value.Substring(2, 3));
                    result.AppendFormat("00{0}", codes[5]);
                    break;
                default:
                    throw new ApplicationException("Unexpected character in barcode.");
            }

            total = 10 - (total % 10);
            result.Append(total == 10 ? 0 : total);

            return result.ToString();
        }

        public static string FromUpcA(string value)
        {
            if (!Regex.IsMatch(value, @"^[01]\d{2}([012]0{4}\d{3}|[3-9]0{4}\d{2}|\d{4}0{4}\d|\d{5}0{4}[5-9])"))
                throw new ArgumentException("UPC A code cannot be compressed.");

            StringBuilder result = new StringBuilder(value);

            if (result[5] != '0')
                result.Remove(6, 4);
            else if (result[4] != '0')
            {
                result.Remove(5, 5);
                result.Insert(6, "4");
            }
            else if (result[3] != '2' && result[3] != '1' && result[3] != '0')
            {
                result.Remove(4, 5);
                result.Insert(6, "3");
            }
            else
            {
                result.Insert(11, result[3]);
                result.Remove(3, 5);
            }

            return result.ToString();
        }
    }
}


<|start_filename|>Barcode Writer/1D/EANHelper.cs<|end_filename|>
﻿
namespace Barcodes
{
    public static class EANHelper
    {
        public const int USACANADA_START = 00;
        public const int USACANADA_END = 13;
        public const int INSTORE_START = 20;
        public const int INSTORE_END = 29;
        public const int FRANCE_START = 30;
        public const int FRANCE_END = 37;
        public const int GERMANY_START = 40;
        public const int GERMANY_END = 44;
        public const int JAPAN1 = 45;
        public const int RUSSIANFEDERATION = 46;
        public const int TAIWAN = 471;
        public const int ESTONIA = 474;
        public const int LATVIA = 475;
        public const int LITHUANIA = 477;
        public const int SRILANKA = 479;
        public const int PHILIPPINES = 480;
        public const int UKRAINE = 482;
        public const int MOLDOVA = 484;
        public const int ARMENIA = 485;
        public const int GEORGIA = 486;
        public const int KAZAKHSTAN = 487;
        public const int HONGKONG = 489;
        public const int JAPAN2 = 49;
        public const int UNITEDKINGDOM = 50;
        public const int GREECE = 520;
        public const int LEBANON = 528;
        public const int CYPRUS = 529;
        public const int MACEDONIA = 531;
        public const int MALTA = 535;
        public const int IRELAND = 539;
        public const int BELGIUM_LUXEMBOURG = 54;
        public const int PORTUGAL = 560;
        public const int ICELAND = 569;
        public const int DENMARK = 57;
        public const int POLAND = 590;
        public const int ROMANIA = 594;
        public const int HUNGARY = 599;
        public const int SOUTHAFRICA_START = 600;
        public const int SOUTHAFRICA_END = 601;
        public const int MAURITIUS = 609;
        public const int MOROCCO = 611;
        public const int ALGERIA = 613;
        public const int TUNISIA = 619;
        public const int EGYPT = 622;
        public const int JORDAN = 625;
        public const int IRAN = 626;
        public const int FINLAND = 64;
        public const int CHINA_START = 690;
        public const int CHINA_END = 692;
        public const int NORWAY = 70;
        public const int ISRAEL = 729;
        public const int SWEDEN = 73;
        public const int GUATEMALA = 740;
        public const int ELSALVADOR = 741;
        public const int HONDURAS = 742;
        public const int NICARAGUA = 743;
        public const int COSTARICA = 744;
        public const int DOMINICANREPUBLIC = 746;
        public const int MEXICO = 750;
        public const int VENEZUELA = 759;
        public const int SWITZERLAND = 76;
        public const int COLOMBIA = 770;
        public const int URUGUAY = 773;
        public const int PERU1 = 775;
        public const int BOLIVIA = 777;
        public const int ARGENTINA = 779;
        public const int CHILE = 780;
        public const int PARAGUAY = 784;
        public const int PERU2 = 785;
        public const int ECUADOR = 786;
        public const int BRAZIL = 789;
        public const int ITALY_START = 80;
        public const int ITALY_END = 83;
        public const int SPAIN = 84;
        public const int CUBA = 850;
        public const int SLOVAKIA = 858;
        public const int CZECHREPUBLIC = 859;
        public const int YUGLOSLAVIA = 860;
        public const int TURKEY = 869;
        public const int NETHERLANDS = 87;
        public const int SOUTHKOREA = 880;
        public const int THAILAND = 885;
        public const int SINGAPORE = 888;
        public const int INDIA = 890;
        public const int VIETNAM = 893;
        public const int INDONESIA = 899;
        public const int AUSTRIA_START = 90;
        public const int AUSTRIA_END = 91;
        public const int AUSTRALIA = 93;
        public const int NEWZEALAND = 94;
        public const int MALAYSIA = 955;
        public const int ISSN = 977;//International Standard Serial Number for Periodicals
        public const int ISBN = 978;// International Standard Book Numbering (ISBN) 	 	
        public const int ISMN = 979;//International Standard Music Number (ISMN) 	 	
        public const int REFUNDRECEIPTS = 980;
        public const int COMMONCURRENCYCOUPONS_START = 981;
        public const int COMMONCURRENCYCOUPONS_END = 982;
        public const int COUPONS = 99;

        public const int UPC_REGULAR0 = 0;
        public const int UPC_INSTOREWEIGHT = 2;
        public const int UPC_DRUGHEALTH = 3;
        public const int UPC_INSTORENONFOOD = 4;
        public const int UPC_COUPONS = 5;
        public const int UPC_REGULAR7 = 7;

        public const int UPC5_DOLLARS = 50000;
        public const int UPC5_POUNDS = 0;
        public const int UPC5_NOSRP = 90000;
        public const int UPC5_NOCOST = 99991;
        public const int UPC5_USED = 99990;
    }
}


<|start_filename|>Barcodes2/AsciiEncoder.cs<|end_filename|>
﻿using System;

namespace Barcodes2
{
    /// <summary>
    /// ASCII encoder used by 1D barcodes, such as Extended 3of9
    /// </summary>
    internal static class AsciiEncoder
    {
        /// <summary>
        /// Lookup the value string for a given ASCII value
        /// </summary>
        /// <param name="value">ASCII value less than 0x80</param>
        /// <returns>the encoded value string</returns>
        public static string Lookup(char value)
        {
            if (value > 127)
                throw new ArgumentException("The value to encode contained characters not supported by this barcode.");

            if (System.Text.RegularExpressions.Regex.IsMatch(value.ToString(), "[A-Z0-9 -\\.]"))
                return value.ToString();

            if (value == 0)
                return "%U";
            if (value == 64)
                return "%V";
            if (value == 96)
                return "%W";

            if (value > 0 && value < 27)
                return string.Format("${0}", (char)(value + 64));
            if (value > 32 && value < 59)
                return string.Format("/{0}", (char)(value + 32));
            if (value > 96 && value < 123)
                return string.Format("+{0}", (char)(value - 32));

            if (value > 26 && value < 32)
                return string.Format("%{0}", (char)(value + 38));
            if (value > 58 && value < 64)
                return string.Format("%{0}", (char)(value + 11));
            if (value > 90 && value < 96)
                return string.Format("%{0}", (char)(value - 16));
            if (value > 122)
                return string.Format("%{0}", (char)(value - 43));

            throw new ApplicationException("The character could not encoded.");
        }
    }
}


<|start_filename|>Barcode Writer/AddChecksumEventArgs.cs<|end_filename|>
﻿using System;

namespace Barcodes
{
	public class AddChecksumEventArgs : EventArgs
	{
		public string Text
		{
			get;
			set;
		}

		public CodedValueCollection Codes
		{
			get;
			private set;
		}

		public AddChecksumEventArgs(string text, CodedValueCollection codes)
		{
			Text = text;
			Codes = codes;
		}

		public AddChecksumEventArgs(State state)
		{
			Text = state.Text;
			Codes = state.Codes;
		}
	}
}


<|start_filename|>Barcode Writer/BarcodeBase.cs<|end_filename|>
﻿#define MEASURE
#define MARKER

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

namespace Barcodes
{
	/// <summary>
	/// Abstract class for all barcodes
	/// </summary>
	public abstract class BarcodeBase
	{
		protected static object TheLock = new object();

		//public static BarcodeBase2 Instance;
		public event EventHandler<AddChecksumEventArgs> AddChecksum;

		/// <summary>
		/// Gets or sets the list of patterns to draw
		/// </summary>
		protected static Dictionary<int, Pattern> PatternSet
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the allowed characters expression
		/// </summary>
		protected System.Text.RegularExpressions.Regex AllowedCharsPattern
		{
			get;
			set;
		}

		/// <summary>
		/// Gets the default settings for the barcode
		/// </summary>
		public BarcodeSettings DefaultSettings
		{
			get;
			protected set;
		}

		public BarcodeBase()
			: this(new BarcodeSettings())
		{ }

		public BarcodeBase(BarcodeSettings settings)
		{
			DefaultSettings = settings;

			Init();

			if (PatternSet == null)
			{
				lock (TheLock)
				{
					if (PatternSet == null)
						CreatePatternSet();
				}
			}
		}

		#region Drawing methods

		/// <summary>
		/// Test method for adding a measure along the top of the image
		/// </summary>
		/// <param name="settings">Settings to sue for calculations</param>
		/// <param name="width">width of the image in pixels</param>
		/// <param name="canvas">Canvas to draw on</param>
		protected void AddMeasure(State state)
		{
			int left = 0;
			bool alt = true;

			while (left < state.Canvas.VisibleClipBounds.Width)
			{
				if (alt)
					state.Canvas.FillRectangle(Brushes.Gainsboro, left, 0, 1, state.Settings.TopMargin);
				left++;
				alt = !alt;
			}
		}

		/// <summary>
		/// Draws the text below the barcode
		/// </summary>
		/// <param name="canvas">the canvas object on which to draw</param>
		/// <param name="settings">the settigns file in use for the barcode</param>
		/// <param name="text">the text to draw</param>
		/// <param name="width">The width of the barcode to align the text</param>
		protected virtual void PaintText(State state)
		{
			if (!state.Settings.IsTextShown)
				return;

			string text = PadText(state);

			SizeF textSize = state.Canvas.MeasureString(text, state.Settings.Font);
			int x = (int)(state.Canvas.VisibleClipBounds.Width / 2) - ((int)textSize.Width / 2);
			int y = state.Settings.TopMargin + state.Settings.BarHeight + state.Settings.TextPadding;

			state.Canvas.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
			state.Canvas.DrawString(text, state.Settings.Font, Brushes.Black, x, y);
		}

		/// <summary>
		/// If the barcode requires the text to be limited with a character(s), this adds them
		/// </summary>
		/// <param name="value">the text to pad</param>
		/// <param name="settings">the settings in use</param>
		/// <returns>the text with any padding added</returns>
		protected string PadText(State state)
		{
			if (!state.Settings.IsTextPadded)
				return state.Text;


			StringBuilder sb = new StringBuilder();
			//sb.Append(" ");
			foreach (char item in state.Text)
			{
				sb.AppendFormat("{0} ", item);
			}
			return sb.ToString();
		}

		protected Rectangle[] DrawPattern(Pattern pattern, State state)
		{
			List<Rectangle> rects = new List<Rectangle>();

			int offset = (state.Settings.MediumHeight - state.Settings.ShortHeight);
			int left = state.Left;
			Rectangle rect;
			foreach (Elements item in pattern.Elements)
			{
				switch (item)
				{
					case Elements.WideBlack:
						rect = new Rectangle(left, state.Top, state.Settings.WideWidth, state.Settings.BarHeight);
						left += state.Settings.WideWidth;

						rects.Add(rect);
						break;
					case Elements.WideWhite:
						left += state.Settings.WideWidth;
						break;
					case Elements.NarrowBlack:
						rect = new Rectangle(left, state.Top, state.Settings.NarrowWidth, state.Settings.BarHeight);
						left += state.Settings.NarrowWidth;

						rects.Add(rect);
						break;
					case Elements.NarrowWhite:
						left += state.Settings.NarrowWidth;
						break;
					case Elements.Tracker:
						rect = new Rectangle(left, state.Top + offset, state.Settings.NarrowWidth, state.Settings.ShortHeight);
						left += state.Settings.NarrowWidth;
						rects.Add(rect);
						break;
					case Elements.Ascender:
						rect = new Rectangle(left, state.Top, state.Settings.NarrowWidth, state.Settings.MediumHeight);
						left += state.Settings.NarrowWidth;
						rects.Add(rect);
						break;
					case Elements.Descender:
						rect = new Rectangle(left, state.Top + offset, state.Settings.NarrowWidth, state.Settings.MediumHeight);
						left += state.Settings.NarrowWidth;
						rects.Add(rect);
						break;
				}
			}

			return rects.ToArray();
		}

		/// <summary>
		/// Main function to draw the barcode
		/// </summary>
		/// <param name="settings">setting in use with this barcode</param>
		/// <param name="text">text to encode</param>
		/// <returns>bitmap image of the barcode</returns>
		protected Bitmap Paint(BarcodeSettings settings, string text)
		{
			State state = new State(settings, settings.LeftMargin, settings.TopMargin);
			state.Codes = new CodedValueCollection();
			state.Text = ParseText(text, state.Codes);

			if (settings.IsChecksumCalculated)
			{
				AddChecksumEventArgs args = new AddChecksumEventArgs(state);
				OnAddChecksum(args);
				state.Text = args.Text;
			}

			Size size = GetDimensions(settings, state.Codes);

			Bitmap b = new Bitmap(size.Width, size.Height);//, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);
			state.Canvas = Graphics.FromImage(b);

			Paint(state);

			return b;
		}

		protected void Paint(State state)
		{
			state.Canvas.ScaleTransform(state.Settings.Scale, state.Settings.Scale);
			state.Canvas.Clear(Color.White);

#if MEASURE
			AddMeasure(state);
#endif
			OnBeforeDrawCode(state);

#if MARKER
			bool isGrey = true;
#endif

			for (int i = 0; i < state.Codes.Count; i++)
			{
				state.ModuleValue = (char)state.Codes[i];
				OnBeforeDrawModule(state, i);

#if MARKER
				if (isGrey)
					state.Canvas.FillRectangle(Brushes.Gray, state.Left, 0, (PatternSet[state.Codes[i]].WideCount * state.Settings.WideWidth) + (PatternSet[state.Codes[i]].NarrowCount * state.Settings.NarrowWidth), state.Canvas.VisibleClipBounds.Height);
				isGrey = !isGrey;
#endif
				Rectangle[] r = DrawPattern(PatternSet[state.Codes[i]], state);
				if (r.Length > 0)
					state.Canvas.FillRectangles(Brushes.Black, r);


				OnAfterDrawModule(state, i);
			}

			OnAfterDrawCode(state);
			PaintText(state);
		}

		/// <summary>
		/// Calculates the size of the barcode image &amp; sets the margins if a size is defined
		/// </summary>
		/// <param name="settings">setting in use with this barcode</param>
		/// <param name="codes">The encoded barcode data</param>
		/// <returns>size of the resultant image</returns>
		private Size GetDimensions(BarcodeSettings settings, CodedValueCollection codes)
		{
			int width = OnCalculateWidth(0, settings, codes);
			int height = OnCalculateHeight(0, settings, codes);

			if (settings.MaxWidth > 0 && width > settings.MaxWidth)
				throw new BarcodeSizeException("The barcode width exceeds the maximum allowed width");
			if (settings.MaxHeight > 0 && height > settings.MaxHeight)
				throw new BarcodeSizeException("The barcode height exceeds the maximum allowed height");

			if (settings.Width > 0)
			{
				if (settings.Width < width)
					throw new BarcodeSizeException("The barcode width is larger than the defined width");

				settings.LeftMargin = (settings.Width - width) / 2;
				settings.RightMargin = settings.Width - width - settings.LeftMargin;
				width = settings.Width;
			}
			if (settings.Height > 0)
			{
				if (settings.Height < height)
					throw new BarcodeSizeException("The barcode height is larger than the defined height");
				settings.TopMargin = (settings.Height - height) / 2;
				settings.BottomMargin = settings.Height - height - settings.TopMargin;
				height = settings.Height;
			}

			return new Size((int)Math.Ceiling(width * settings.Scale), (int)Math.Ceiling(height * settings.Scale));
		}

		#endregion

		/// <summary>
		/// Parses the text into encodable characters
		/// </summary>
		/// <param name="value">the text to encode</param>
		/// <param name="codes">the code set to sue for encoding</param>
		/// <returns>the text after any clean-up</returns>
		protected virtual string ParseText(string value, CodedValueCollection codes)
		{
			if (!IsValidData(value))
				throw new ApplicationException();

			return value;
		}

		/// <summary>
		/// Main entry point for generating the barcode
		/// </summary>
		/// <param name="text">text to encode</param>
		/// <returns>bitmap of the generated barcode</returns>
		public Bitmap Generate(string text)
		{
			return Generate(text, DefaultSettings);
		}

		/// <summary>
		/// Main entry point for generating the barcode
		/// </summary>
		/// <param name="text">text to encode</param>
		/// <param name="settings">setting to use to overide the defaults</param>
		/// <returns>bitmap of the generated barcode</returns>
		public Bitmap Generate(string text, BarcodeSettings settings)
		{
			return Paint(settings, text);
		}

		/// <summary>
		/// Validates the text to ensure the barcode encoding scheme can support it.
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		public virtual bool IsValidData(string value)
		{
			return AllowedCharsPattern.IsMatch(value);
		}

		#region Event Raises

		/// <summary>
		/// Modify the width calculation
		/// </summary>
		/// <param name="width">calculated pixel width</param>
		/// <param name="codes">parsed value</param>
		/// <returns>new pixel width</returns>
		protected virtual int OnCalculateWidth(int width, BarcodeSettings settings, CodedValueCollection codes)
		{
			return width + settings.LeftMargin + settings.RightMargin + ((codes.Count - 1) * settings.ModulePadding);
		}

		/// <summary>
		/// Modify the height
		/// </summary>
		/// <param name="height">calculated pixel height</param>
		/// <param name="codes">parsed value</param>
		/// <returns>new pixel height</returns>
		protected virtual int OnCalculateHeight(int height, BarcodeSettings settings, CodedValueCollection codes)
		{
			
			height = settings.TopMargin + settings.BarHeight + settings.BottomMargin;
			
			if (settings.IsTextShown)
				height += Convert.ToInt32(settings.Font.GetHeight()) + settings.TextPadding;

			return height;
		}

		/// <summary>
		/// Occurs before the barcode is drawn
		/// </summary>
		/// <param name="state">drawing state object</param>
		protected virtual void OnBeforeDrawCode(State state)
		{
		}

		/// <summary>
		/// Occurs inbetween characters. Each character is a "module"
		/// </summary>
		/// <param name="state">drawing state</param>
		/// <param name="index">module index in the text to encode</param>
		protected virtual void OnBeforeDrawModule(State state, int index)
		{
		}

		/// <summary>
		/// Occurs after a module has been drawn
		/// </summary>
		/// <param name="state"></param>
		/// <param name="index"></param>
		protected virtual void OnAfterDrawModule(State state, int index)
		{
			state.Left += (PatternSet[state.ModuleValue].WideCount * state.Settings.WideWidth) + (PatternSet[state.ModuleValue].NarrowCount * state.Settings.NarrowWidth) + state.Settings.ModulePadding;
		}

		/// <summary>
		/// Occurs after the last module drawn
		/// </summary>
		/// <param name="state">drawing state object</param>
		protected virtual void OnAfterDrawCode(State state)
		{
		}

		/// <summary>
		/// Fires the add checksum event
		/// </summary>
		/// <param name="e">Arguments for the add checksum event</param>
		protected virtual void OnAddChecksum(AddChecksumEventArgs e)
		{
			if (AddChecksum == null)
				return;

			AddChecksum(this, e);
		}

		#endregion

		/// <summary>
		/// If the barcode supports a check digit, add it to the string
		/// </summary>
		/// <param name="value">barcode value to use for calculation</param>
		/// <returns>check digit to return</returns>
		public virtual string AddCheckDigit(string value)
		{
			CodedValueCollection codes = new CodedValueCollection();

			value = ParseText(value, codes);
			AddChecksumEventArgs e = new AddChecksumEventArgs(value, codes);
			OnAddChecksum(e);

			return e.Text;
		}

		#region To Implement

		/// <summary>
		/// initialises the barcode generator
		/// </summary>
		protected abstract void Init();

		/// <summary>
		/// Create the patterns in the static Patternset
		/// </summary>
		protected abstract void CreatePatternSet();

		#endregion
	}
}
