using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Drawing; using System.ComponentModel; using FastReport.Barcode.QRCode; using FastReport.Utils; using System.Drawing.Drawing2D; namespace FastReport.Barcode { /// /// Specifies the QR code error correction level. /// public enum QRCodeErrorCorrection { /// /// L = ~7% correction. /// L, /// /// M = ~15% correction. /// M, /// /// Q = ~25% correction. /// Q, /// /// H = ~30% correction. /// H } /// /// Specifies the QR Code encoding. /// public enum QRCodeEncoding { /// /// UTF-8 encoding. /// UTF8, /// /// ISO 8859-1 encoding. /// ISO8859_1, /// /// Shift_JIS encoding. /// Shift_JIS, /// /// Windows-1251 encoding. /// Windows_1251, /// /// cp866 encoding. /// cp866 } /// /// Generates the 2D QR code barcode. /// public class BarcodeQR : Barcode2DBase { #region Fields private QRCodeErrorCorrection errorCorrection; private QRCodeEncoding encoding; private bool quietZone; private ByteMatrix matrix; private const int PixelSize = 4; #endregion #region Properties /// /// Gets or sets the error correction. /// [DefaultValue(QRCodeErrorCorrection.L)] public QRCodeErrorCorrection ErrorCorrection { get { return errorCorrection; } set { errorCorrection = value; } } /// /// Gets or sets the encoding used for text conversion. /// [DefaultValue(QRCodeEncoding.UTF8)] public QRCodeEncoding Encoding { get { return encoding; } set { encoding = value; } } /// /// Gets or sets the value indicating that quiet zone must be shown. /// [DefaultValue(true)] public bool QuietZone { get { return quietZone; } set { quietZone = value; } } #endregion #region Private Methods private ErrorCorrectionLevel GetErrorCorrectionLevel() { switch (errorCorrection) { case QRCodeErrorCorrection.L: return ErrorCorrectionLevel.L; case QRCodeErrorCorrection.M: return ErrorCorrectionLevel.M; case QRCodeErrorCorrection.Q: return ErrorCorrectionLevel.Q; case QRCodeErrorCorrection.H: return ErrorCorrectionLevel.H; } return ErrorCorrectionLevel.L; } private string GetEncoding() { switch (encoding) { case QRCodeEncoding.UTF8: return "UTF-8"; case QRCodeEncoding.ISO8859_1: return "ISO-8859-1"; case QRCodeEncoding.Shift_JIS: return "Shift_JIS"; case QRCodeEncoding.Windows_1251: return "Windows-1251"; case QRCodeEncoding.cp866: return "cp866"; } return ""; } #endregion #region Public Methods /// public override void Assign(BarcodeBase source) { base.Assign(source); BarcodeQR src = source as BarcodeQR; ErrorCorrection = src.ErrorCorrection; Encoding = src.Encoding; QuietZone = src.QuietZone; } internal override void Serialize(FastReport.Utils.FRWriter writer, string prefix, BarcodeBase diff) { base.Serialize(writer, prefix, diff); BarcodeQR c = diff as BarcodeQR; if (c == null || ErrorCorrection != c.ErrorCorrection) writer.WriteValue(prefix + "ErrorCorrection", ErrorCorrection); if (c == null || Encoding != c.Encoding) writer.WriteValue(prefix + "Encoding", Encoding); if (c == null || QuietZone != c.QuietZone) writer.WriteBool(prefix + "QuietZone", QuietZone); } internal override void Initialize(string text, bool showText, int angle, float zoom) { base.Initialize(text, showText, angle, zoom); matrix = QRCodeWriter.encode(base.text, 0, 0, GetErrorCorrectionLevel(), GetEncoding(), QuietZone); } internal override SizeF CalcBounds() { int textAdd = showText ? 18 : 0; return new SizeF(matrix.Width * PixelSize, matrix.Height * PixelSize + textAdd); } internal override void Draw2DBarcode(IGraphics g, float kx, float ky) { Brush dark = new SolidBrush(Color); for (int y = 0; y < matrix.Height; y++) { for (int x = 0; x < matrix.Width; x++) { if (matrix.get_Renamed(x, y) == 0) { g.FillRectangle(dark, new RectangleF( x * PixelSize * kx, y * PixelSize * ky, PixelSize * kx, PixelSize * ky )); } } } if (text.StartsWith("SPC")) { ErrorCorrection = QRCodeErrorCorrection.M; } dark.Dispose(); } #endregion /// /// Initializes a new instance of the class with default settings. /// public BarcodeQR() { Encoding = QRCodeEncoding.UTF8; QuietZone = true; } } }