BarcodeQR.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using System.Drawing;
  6. using System.ComponentModel;
  7. using FastReport.Barcode.QRCode;
  8. using FastReport.Utils;
  9. using System.Drawing.Drawing2D;
  10. namespace FastReport.Barcode
  11. {
  12. /// <summary>
  13. /// Specifies the QR code error correction level.
  14. /// </summary>
  15. public enum QRCodeErrorCorrection
  16. {
  17. /// <summary>
  18. /// L = ~7% correction.
  19. /// </summary>
  20. L,
  21. /// <summary>
  22. /// M = ~15% correction.
  23. /// </summary>
  24. M,
  25. /// <summary>
  26. /// Q = ~25% correction.
  27. /// </summary>
  28. Q,
  29. /// <summary>
  30. /// H = ~30% correction.
  31. /// </summary>
  32. H
  33. }
  34. /// <summary>
  35. /// Specifies the QR Code encoding.
  36. /// </summary>
  37. public enum QRCodeEncoding
  38. {
  39. /// <summary>
  40. /// UTF-8 encoding.
  41. /// </summary>
  42. UTF8,
  43. /// <summary>
  44. /// ISO 8859-1 encoding.
  45. /// </summary>
  46. ISO8859_1,
  47. /// <summary>
  48. /// Shift_JIS encoding.
  49. /// </summary>
  50. Shift_JIS,
  51. /// <summary>
  52. /// Windows-1251 encoding.
  53. /// </summary>
  54. Windows_1251,
  55. /// <summary>
  56. /// cp866 encoding.
  57. /// </summary>
  58. cp866
  59. }
  60. /// <summary>
  61. /// Generates the 2D QR code barcode.
  62. /// </summary>
  63. public class BarcodeQR : Barcode2DBase
  64. {
  65. #region Fields
  66. private QRCodeErrorCorrection errorCorrection;
  67. private QRCodeEncoding encoding;
  68. private bool quietZone;
  69. private ByteMatrix matrix;
  70. private const int PixelSize = 4;
  71. #endregion
  72. #region Properties
  73. /// <summary>
  74. /// Gets or sets the error correction.
  75. /// </summary>
  76. [DefaultValue(QRCodeErrorCorrection.L)]
  77. public QRCodeErrorCorrection ErrorCorrection
  78. {
  79. get { return errorCorrection; }
  80. set { errorCorrection = value; }
  81. }
  82. /// <summary>
  83. /// Gets or sets the encoding used for text conversion.
  84. /// </summary>
  85. [DefaultValue(QRCodeEncoding.UTF8)]
  86. public QRCodeEncoding Encoding
  87. {
  88. get { return encoding; }
  89. set { encoding = value; }
  90. }
  91. /// <summary>
  92. /// Gets or sets the value indicating that quiet zone must be shown.
  93. /// </summary>
  94. [DefaultValue(true)]
  95. public bool QuietZone
  96. {
  97. get { return quietZone; }
  98. set { quietZone = value; }
  99. }
  100. #endregion
  101. #region Private Methods
  102. private ErrorCorrectionLevel GetErrorCorrectionLevel()
  103. {
  104. switch (errorCorrection)
  105. {
  106. case QRCodeErrorCorrection.L:
  107. return ErrorCorrectionLevel.L;
  108. case QRCodeErrorCorrection.M:
  109. return ErrorCorrectionLevel.M;
  110. case QRCodeErrorCorrection.Q:
  111. return ErrorCorrectionLevel.Q;
  112. case QRCodeErrorCorrection.H:
  113. return ErrorCorrectionLevel.H;
  114. }
  115. return ErrorCorrectionLevel.L;
  116. }
  117. private string GetEncoding()
  118. {
  119. switch (encoding)
  120. {
  121. case QRCodeEncoding.UTF8:
  122. return "UTF-8";
  123. case QRCodeEncoding.ISO8859_1:
  124. return "ISO-8859-1";
  125. case QRCodeEncoding.Shift_JIS:
  126. return "Shift_JIS";
  127. case QRCodeEncoding.Windows_1251:
  128. return "Windows-1251";
  129. case QRCodeEncoding.cp866:
  130. return "cp866";
  131. }
  132. return "";
  133. }
  134. #endregion
  135. #region Public Methods
  136. /// <inheritdoc/>
  137. public override void Assign(BarcodeBase source)
  138. {
  139. base.Assign(source);
  140. BarcodeQR src = source as BarcodeQR;
  141. ErrorCorrection = src.ErrorCorrection;
  142. Encoding = src.Encoding;
  143. QuietZone = src.QuietZone;
  144. }
  145. internal override void Serialize(FastReport.Utils.FRWriter writer, string prefix, BarcodeBase diff)
  146. {
  147. base.Serialize(writer, prefix, diff);
  148. BarcodeQR c = diff as BarcodeQR;
  149. if (c == null || ErrorCorrection != c.ErrorCorrection)
  150. writer.WriteValue(prefix + "ErrorCorrection", ErrorCorrection);
  151. if (c == null || Encoding != c.Encoding)
  152. writer.WriteValue(prefix + "Encoding", Encoding);
  153. if (c == null || QuietZone != c.QuietZone)
  154. writer.WriteBool(prefix + "QuietZone", QuietZone);
  155. }
  156. internal override void Initialize(string text, bool showText, int angle, float zoom)
  157. {
  158. base.Initialize(text, showText, angle, zoom);
  159. matrix = QRCodeWriter.encode(base.text, 0, 0, GetErrorCorrectionLevel(), GetEncoding(), QuietZone);
  160. }
  161. internal override SizeF CalcBounds()
  162. {
  163. int textAdd = showText ? 18 : 0;
  164. return new SizeF(matrix.Width * PixelSize, matrix.Height * PixelSize + textAdd);
  165. }
  166. internal override void Draw2DBarcode(IGraphics g, float kx, float ky)
  167. {
  168. Brush dark = new SolidBrush(Color);
  169. for (int y = 0; y < matrix.Height; y++)
  170. {
  171. for (int x = 0; x < matrix.Width; x++)
  172. {
  173. if (matrix.get_Renamed(x, y) == 0)
  174. {
  175. g.FillRectangle(dark, new RectangleF(
  176. x * PixelSize * kx,
  177. y * PixelSize * ky,
  178. PixelSize * kx,
  179. PixelSize * ky
  180. ));
  181. }
  182. }
  183. }
  184. if (text.StartsWith("SPC"))
  185. {
  186. ErrorCorrection = QRCodeErrorCorrection.M;
  187. }
  188. dark.Dispose();
  189. }
  190. #endregion
  191. /// <summary>
  192. /// Initializes a new instance of the <see cref="BarcodeQR"/> class with default settings.
  193. /// </summary>
  194. public BarcodeQR()
  195. {
  196. Encoding = QRCodeEncoding.UTF8;
  197. QuietZone = true;
  198. }
  199. }
  200. }