using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; namespace Barcoded { public abstract class LinearEncoder { protected LinearEncoder(Symbology symbology) { Symbology = symbology; } /// /// Encode the value using the barcode symbology selected. /// /// protected abstract void Encode(string barcodeValue); internal void Generate(string barcodeValue) { EncodedValue = BarcodeValidator.Parse(barcodeValue, Symbology); Encode(EncodedValue); } /// /// Set the minimum barcode height for the barcode symbology used. /// internal abstract void SetMinBarcodeHeight(); /// /// Set the minimum XDimension for the barcode symbology used. /// internal abstract void SetMinXDimension(); /// /// Get the generated barcode as a bitmap image. /// /// /// Barcode image internal MemoryStream GetImage(string barcodeValue) { LinearEncoding.Clear(); Generate(barcodeValue); return LinearRenderer.DrawImageMemoryStream(this); } /// /// Reset the Property Changed flag to false. /// internal void ResetPropertyChanged() { PropertyChanged = false; } /// /// Internal Barcode Value that can be reached by the renderer. /// public string EncodedValue { get; internal set; } /// /// Barcode symbology. /// public Symbology Symbology { get; set; } /// /// Encoder description. /// public string Description { get; internal set; } internal LinearEncoding LinearEncoding { get; } = new LinearEncoding(); /// /// ZPL encoded string. /// internal string ZplEncode { get; set; } /// /// Used to detect if any properties have changed. /// public bool PropertyChanged { get; internal set; } /// /// Symbology specific validator. /// internal abstract ILinearValidator BarcodeValidator { get; } private string _humanReadableValue = ""; /// /// The human readable value. /// public string HumanReadableValue { get => _humanReadableValue; set { _humanReadableValue = value; PropertyChanged = true; } } private bool _humanReadableSymbolAligned; /// /// Sets the human readable label to align with associated barcode symbol /// public bool HumanReadableSymbolAligned { get => _humanReadableSymbolAligned; set { _humanReadableSymbolAligned = value; PropertyChanged = true; } } /// /// Sets the visibility and position of the human readable value. /// Hidden, Above, Below, Embedded /// public HumanReadablePosition HumanReadablePosition { get; private set; } public void SetHumanReadablePosition(string position) { switch(position.ToUpper()) { case "ABOVE": HumanReadablePosition = HumanReadablePosition.Above; break; case "TOP": HumanReadablePosition = HumanReadablePosition.Above; break; case "BELOW": HumanReadablePosition = HumanReadablePosition.Below; break; case "BOTTOM": HumanReadablePosition = HumanReadablePosition.Below; break; case "HIDDEN": HumanReadablePosition = HumanReadablePosition.Hidden; break; case "EMBEDDED": HumanReadablePosition = HumanReadablePosition.Embedded; break; default: HumanReadablePosition = HumanReadablePosition.Hidden; break; } PropertyChanged = true; } /// /// The font to be used for the human readable value, if shown. /// Will default to the system default font if not set. /// public Font HumanReadableFont { get; internal set; } = SystemFonts.DefaultFont; /// /// Set the font to be used for the human readable label. /// /// /// public void SetHumanReadableFont(string fontFamily, int pointSize) { if(pointSize < 1) { pointSize = (int)SystemFonts.DefaultFont.Size; } try { HumanReadableFont = new Font(new FontFamily(fontFamily), pointSize); } catch (Exception) { HumanReadableFont = SystemFonts.DefaultFont; } PropertyChanged = true; } private const int BarcodeHeightMin = 1; private const int BarcodeHeightMax = 2400; private int _barcodeHeight = 1; /// /// Sets the desired height in pixels for the barcode element of the image. /// public int BarcodeHeight { get => _barcodeHeight; set { int barcodeHeightOriginal = value; _barcodeHeight = (value < BarcodeHeightMin) ? BarcodeHeightMin : (value > BarcodeHeightMax) ? BarcodeHeightMax : value; if(barcodeHeightOriginal != _barcodeHeight) { BarcodeHeightChanged = true; } PropertyChanged = true; } } private int _xDimension = 1; /// /// X-dimension is the width of the narrowest bar element in the barcode. /// All other bar and spaces widths in the barcode are a multiple of this value. /// public int XDimension { get => _xDimension; set { _xDimension = value; PropertyChanged = true; } } private int _wideBarRatio = 3; /// /// X-dimension is the width of the narrowest bar element in the barcode. /// All other bar and spaces widths in the barcode are a multiple of this value. /// public int WideBarRatio { get => _wideBarRatio; set { _wideBarRatio = value > 2? 3 : 2; PropertyChanged = true; } } private const int DpiMin = 1; private const int DpiMax = 600; private int _dpi = 300; /// /// Sets the desired image dpi. /// public int Dpi { get => _dpi; set { int dpiOriginal = value; _dpi = (value < DpiMin) ? DpiMin : (value > DpiMax) ? DpiMax : value; if(dpiOriginal != _dpi) { DpiChanged = true; } PropertyChanged = true; } } private int _targetWidth; /// /// Target pixel width for the barcode. /// If set, the encoder will attempt to get as close to this value without exceeding, when generating the barcode /// public int TargetWidth { get => _targetWidth; set { _targetWidth = value; PropertyChanged = true; } } private bool _showEncoding; /// /// When true, will include a human readable label of the barcode encoding values /// for the corresponding part of the barcode. The position of this label will adjust /// top or bottom, dependent on the use of a human readable value and its position. Default is top. /// public bool ShowEncoding { get => _showEncoding; set { _showEncoding = value; PropertyChanged = true; } } /// /// The font to be used for the encoding label if shown. /// Will default to the system default font, if not set. /// public FontFamily EncodingFontFamily { get; private set; } = SystemFonts.DefaultFont.FontFamily; public void SetEncodingFontFamily(string fontFamily) { try { EncodingFontFamily = new FontFamily(fontFamily); } catch (Exception) { EncodingFontFamily = SystemFonts.DefaultFont.FontFamily; } PropertyChanged = true; } private bool _quietzone; /// /// Sets the starting subset to "A" or "B", where an explicit subset is not required. /// Will default to "A" if not set. /// public bool Quietzone { get => _quietzone; set { _quietzone = value; PropertyChanged = true; } } public ImageCodecInfo ImageCodec { get; private set; } = ImageHelpers.FindCodecInfo("PNG"); public string CodecName { get => ImageCodec.FormatDescription; set { ImageCodec = ImageHelpers.FindCodecInfo(value); PropertyChanged = true; } } /// /// Width of the generated barcode. /// public int BarcodeWidth { get; internal set; } /// /// Indicates if the X-dimension was altered to accomodate symbology constraints. /// public bool XDimensionChanged { get; internal set; } /// /// Indicates if the barcode height was altered to accomodate symbology constraints. /// public bool BarcodeHeightChanged { get; internal set; } /// /// Indicates if DPI was adjusted to fit system set constraints. /// public bool DpiChanged { get; internal set; } /// /// Indicates if the human readable font size was changed to prevent text exceeding barcode width. /// public bool HumanReadableFontSizeChanged { get; internal set; } } }