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.

143 lines
4.7 KiB

  1. #if NET40 || NET461
  2. using System;
  3. using System.Drawing;
  4. namespace Apewer.Internals.QrCode
  5. {
  6. internal class PostscriptQRCode : AbstractQRCode, IDisposable
  7. {
  8. /// <summary>
  9. /// Constructor without params to be used in COM Objects connections
  10. /// </summary>
  11. public PostscriptQRCode() { }
  12. public PostscriptQRCode(QRCodeData data) : base(data) { }
  13. public string GetGraphic(int pointsPerModule, bool epsFormat = false)
  14. {
  15. var viewBox = new Size(pointsPerModule * this.QrCodeData.ModuleMatrix.Count, pointsPerModule * this.QrCodeData.ModuleMatrix.Count);
  16. return this.GetGraphic(viewBox, Color.Black, Color.White, true, epsFormat);
  17. }
  18. public string GetGraphic(int pointsPerModule, Color darkColor, Color lightColor, bool drawQuietZones = true, bool epsFormat = false)
  19. {
  20. var viewBox = new Size(pointsPerModule * this.QrCodeData.ModuleMatrix.Count, pointsPerModule * this.QrCodeData.ModuleMatrix.Count);
  21. return this.GetGraphic(viewBox, darkColor, lightColor, drawQuietZones, epsFormat);
  22. }
  23. public string GetGraphic(int pointsPerModule, string darkColorHex, string lightColorHex, bool drawQuietZones = true, bool epsFormat = false)
  24. {
  25. var viewBox = new Size(pointsPerModule * this.QrCodeData.ModuleMatrix.Count, pointsPerModule * this.QrCodeData.ModuleMatrix.Count);
  26. return this.GetGraphic(viewBox, darkColorHex, lightColorHex, drawQuietZones, epsFormat);
  27. }
  28. public string GetGraphic(Size viewBox, bool drawQuietZones = true, bool epsFormat = false)
  29. {
  30. return this.GetGraphic(viewBox, Color.Black, Color.White, drawQuietZones, epsFormat);
  31. }
  32. public string GetGraphic(Size viewBox, string darkColorHex, string lightColorHex, bool drawQuietZones = true, bool epsFormat = false)
  33. {
  34. return this.GetGraphic(viewBox, ColorTranslator.FromHtml(darkColorHex), ColorTranslator.FromHtml(lightColorHex), drawQuietZones, epsFormat);
  35. }
  36. public string GetGraphic(Size viewBox, Color darkColor, Color lightColor, bool drawQuietZones = true, bool epsFormat = false)
  37. {
  38. var offset = drawQuietZones ? 0 : 4;
  39. var drawableModulesCount = this.QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : offset * 2);
  40. var pointsPerModule = (double)Math.Min(viewBox.Width, viewBox.Height) / (double)drawableModulesCount;
  41. string psFile = string.Format(psHeader, new object[] {
  42. DateTime.Now.ToString("s"), CleanSvgVal(viewBox.Width), CleanSvgVal(pointsPerModule),
  43. epsFormat ? "EPSF-3.0" : string.Empty
  44. });
  45. psFile += string.Format(psFunctions, new object[] {
  46. CleanSvgVal(darkColor.R /255.0), CleanSvgVal(darkColor.G /255.0), CleanSvgVal(darkColor.B /255.0),
  47. CleanSvgVal(lightColor.R /255.0), CleanSvgVal(lightColor.G /255.0), CleanSvgVal(lightColor.B /255.0),
  48. drawableModulesCount
  49. });
  50. for (int xi = offset; xi < offset + drawableModulesCount; xi++)
  51. {
  52. if (xi > offset)
  53. psFile += "nl\n";
  54. for (int yi = offset; yi < offset + drawableModulesCount; yi++)
  55. {
  56. psFile += (this.QrCodeData.ModuleMatrix[xi][yi] ? "f " : "b ");
  57. }
  58. psFile += "\n";
  59. }
  60. return psFile + psFooter;
  61. }
  62. private string CleanSvgVal(double input)
  63. {
  64. //Clean double values for international use/formats
  65. return input.ToString(System.Globalization.CultureInfo.InvariantCulture);
  66. }
  67. private const string psHeader = @"%!PS-Adobe-3.0 {3}
  68. %%Creator: QRCoder.NET
  69. %%Title: QRCode
  70. %%CreationDate: {0}
  71. %%DocumentData: Clean7Bit
  72. %%Origin: 0
  73. %%DocumentMedia: Default {1} {1} 0 () ()
  74. %%BoundingBox: 0 0 {1} {1}
  75. %%LanguageLevel: 2
  76. %%Pages: 1
  77. %%Page: 1 1
  78. %%EndComments
  79. %%BeginConstants
  80. /sz {1} def
  81. /sc {2} def
  82. %%EndConstants
  83. %%BeginFeature: *PageSize Default
  84. << /PageSize [ sz sz ] /ImagingBBox null >> setpagedevice
  85. %%EndFeature
  86. ";
  87. private const string psFunctions = @"%%BeginFunctions
  88. /csquare {{
  89. newpath
  90. 0 0 moveto
  91. 0 1 rlineto
  92. 1 0 rlineto
  93. 0 -1 rlineto
  94. closepath
  95. setrgbcolor
  96. fill
  97. }} def
  98. /f {{
  99. {0} {1} {2} csquare
  100. 1 0 translate
  101. }} def
  102. /b {{
  103. 1 0 translate
  104. }} def
  105. /background {{
  106. {3} {4} {5} csquare
  107. }} def
  108. /nl {{
  109. -{6} -1 translate
  110. }} def
  111. %%EndFunctions
  112. %%BeginBody
  113. 0 0 moveto
  114. gsave
  115. sz sz scale
  116. background
  117. grestore
  118. gsave
  119. sc sc scale
  120. 0 {6} 1 sub translate
  121. ";
  122. private const string psFooter = @"%%EndBody
  123. grestore
  124. showpage
  125. %%EOF
  126. ";
  127. }
  128. }
  129. #endif