Barcode2DBase.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using FastReport.Utils;
  2. using System.Drawing;
  3. namespace FastReport.Barcode
  4. {
  5. /// <summary>
  6. /// The base class for 2D-barcodes such as PDF417 and Datamatrix.
  7. /// </summary>
  8. public abstract class Barcode2DBase : BarcodeBase
  9. {
  10. internal float FontHeight => Font.Height * DrawUtils.ScreenDpiFX * 18 / 13; // 18/13 to be more or less compatible with old behavior (Arial,8 with hardcoded 18px height)
  11. private void DrawBarcode(IGraphics g, float width, float height)
  12. {
  13. SizeF originalSize = CalcBounds();
  14. float kx = width / originalSize.Width;
  15. float ky = height / originalSize.Height;
  16. Draw2DBarcode(g, kx, ky);
  17. //If swiss qr, draw the swiss cross
  18. if (text.StartsWith("SPC"))
  19. {
  20. float top = showText ? height - 21 : height;
  21. g.FillRectangle(Brushes.White, width / 2 - width / 100f * 7, top / 2 - top / 100 * 7, width / 100f * 14, top / 100 * 14);
  22. g.FillRectangle(Brushes.Black, width / 2 - width / 100f * 6, top / 2 - top / 100 * 6, width / 100f * 12, top / 100 * 12);
  23. g.FillRectangle(Brushes.White, width / 2 - width / 100f * 4, top / 2 - top / 100 * 1.5f, width / 100f * 8, top / 100 * 3);
  24. g.FillRectangle(Brushes.White, width / 2 - width / 100f * 1.5f, top / 2 - top / 100 * 4, width / 100f * 3, top / 100 * 8);
  25. }
  26. if (showMarker && text.StartsWith("ST"))
  27. {
  28. using (Pen skyBluePen = new Pen(Brushes.Black))
  29. {
  30. skyBluePen.Width = (kx * 4 * zoom) / 2;
  31. g.DrawLine(skyBluePen, width - 2, height / 2, width - 2, height - 2);
  32. g.DrawLine(skyBluePen, width / 2, height - 2, width - 2, height - 2);
  33. }
  34. }
  35. // draw the text.
  36. if (showText)
  37. {
  38. string data = StripControlCodes(text);
  39. if (data.Length > 0)
  40. {
  41. // When we print, .Net automatically scales the font. However, we need to handle this process.
  42. // Downscale the font to the screen resolution, then scale by required value (ky).
  43. float fontHeight = FontHeight;
  44. float fontZoom = fontHeight / (int)g.MeasureString(data, Font).Height * ky;
  45. using (Font drawFont = new Font(Font.FontFamily, Font.Size * fontZoom, Font.Style))
  46. {
  47. g.DrawString(data, drawFont, Brushes.Black, new RectangleF(0, height - fontHeight * ky, width, fontHeight * ky));
  48. }
  49. }
  50. }
  51. }
  52. internal virtual void Draw2DBarcode(IGraphics g, float kx, float ky)
  53. {
  54. }
  55. /// <inheritdoc/>
  56. public override void DrawBarcode(IGraphics g, RectangleF displayRect)
  57. {
  58. float width = angle == 90 || angle == 270 ? displayRect.Height : displayRect.Width;
  59. float height = angle == 90 || angle == 270 ? displayRect.Width : displayRect.Height;
  60. IGraphicsState state = g.Save();
  61. try
  62. {
  63. // rotate
  64. g.TranslateTransform(displayRect.Left, displayRect.Top);
  65. g.RotateTransform(angle);
  66. switch (angle)
  67. {
  68. case 90:
  69. g.TranslateTransform(0, -displayRect.Width);
  70. break;
  71. case 180:
  72. g.TranslateTransform(-displayRect.Width, -displayRect.Height);
  73. break;
  74. case 270:
  75. g.TranslateTransform(-displayRect.Height, 0);
  76. break;
  77. }
  78. DrawBarcode(g, width, height);
  79. }
  80. finally
  81. {
  82. g.Restore(state);
  83. }
  84. }
  85. }
  86. }