You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
4.3 KiB

  1. #if NET40 || NET461
  2. using System;
  3. using System.Drawing;
  4. using System.Text;
  5. namespace Apewer.Internals.QrCode
  6. {
  7. internal class SvgQRCode : AbstractQRCode, IDisposable
  8. {
  9. /// <summary>
  10. /// Constructor without params to be used in COM Objects connections
  11. /// </summary>
  12. public SvgQRCode() { }
  13. public SvgQRCode(QRCodeData data) : base(data) { }
  14. public string GetGraphic(int pixelsPerModule)
  15. {
  16. var viewBox = new Size(pixelsPerModule*this.QrCodeData.ModuleMatrix.Count, pixelsPerModule * this.QrCodeData.ModuleMatrix.Count);
  17. return this.GetGraphic(viewBox, Color.Black, Color.White);
  18. }
  19. public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
  20. {
  21. var viewBox = new Size(pixelsPerModule * this.QrCodeData.ModuleMatrix.Count, pixelsPerModule * this.QrCodeData.ModuleMatrix.Count);
  22. return this.GetGraphic(viewBox, darkColor, lightColor, drawQuietZones, sizingMode);
  23. }
  24. public string GetGraphic(int pixelsPerModule, string darkColorHex, string lightColorHex, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
  25. {
  26. var viewBox = new Size(pixelsPerModule * this.QrCodeData.ModuleMatrix.Count, pixelsPerModule * this.QrCodeData.ModuleMatrix.Count);
  27. return this.GetGraphic(viewBox, darkColorHex, lightColorHex, drawQuietZones, sizingMode);
  28. }
  29. public string GetGraphic(Size viewBox, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
  30. {
  31. return this.GetGraphic(viewBox, Color.Black, Color.White, drawQuietZones, sizingMode);
  32. }
  33. public string GetGraphic(Size viewBox, Color darkColor, Color lightColor, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
  34. {
  35. return this.GetGraphic(viewBox, ColorTranslator.ToHtml(Color.FromArgb(darkColor.ToArgb())), ColorTranslator.ToHtml(Color.FromArgb(lightColor.ToArgb())), drawQuietZones, sizingMode);
  36. }
  37. public string GetGraphic(Size viewBox, string darkColorHex, string lightColorHex, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
  38. {
  39. var offset = drawQuietZones ? 0 : 4;
  40. var drawableModulesCount = this.QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : offset * 2);
  41. var pixelsPerModule = (double)Math.Min(viewBox.Width, viewBox.Height) / (double)drawableModulesCount;
  42. var qrSize = drawableModulesCount * pixelsPerModule;
  43. var svgSizeAttributes = sizingMode.Equals(SizingMode.WidthHeightAttribute) ? $@"width=""{viewBox.Width}"" height=""{viewBox.Height}""" : $@"viewBox=""0 0 {viewBox.Width} {viewBox.Height}""";
  44. var svgFile = new StringBuilder($@"<svg version=""1.1"" baseProfile=""full"" shape-rendering=""crispEdges"" {svgSizeAttributes} xmlns=""http://www.w3.org/2000/svg"">");
  45. svgFile.AppendLine($@"<rect x=""0"" y=""0"" width=""{CleanSvgVal(qrSize)}"" height=""{CleanSvgVal(qrSize)}"" fill=""{lightColorHex}"" />");
  46. for (int xi = offset; xi < offset + drawableModulesCount; xi++)
  47. {
  48. for (int yi = offset; yi < offset + drawableModulesCount; yi++)
  49. {
  50. if (this.QrCodeData.ModuleMatrix[yi][xi])
  51. {
  52. var x = (xi - offset) * pixelsPerModule;
  53. var y = (yi - offset) * pixelsPerModule;
  54. svgFile.AppendLine($@"<rect x=""{CleanSvgVal(x)}"" y=""{CleanSvgVal(y)}"" width=""{CleanSvgVal(pixelsPerModule)}"" height=""{CleanSvgVal(pixelsPerModule)}"" fill=""{darkColorHex}"" />");
  55. }
  56. }
  57. }
  58. svgFile.Append(@"</svg>");
  59. return svgFile.ToString();
  60. }
  61. private string CleanSvgVal(double input)
  62. {
  63. //Clean double values for international use/formats
  64. return input.ToString(System.Globalization.CultureInfo.InvariantCulture);
  65. }
  66. public enum SizingMode
  67. {
  68. WidthHeightAttribute,
  69. ViewBoxAttribute
  70. }
  71. }
  72. }
  73. #endif