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.

83 lines
4.3 KiB

#if NET40 || NET461
using System;
using System.Drawing;
using System.Text;
namespace Apewer.Internals.QrCode
{
internal class SvgQRCode : AbstractQRCode, IDisposable
{
/// <summary>
/// Constructor without params to be used in COM Objects connections
/// </summary>
public SvgQRCode() { }
public SvgQRCode(QRCodeData data) : base(data) { }
public string GetGraphic(int pixelsPerModule)
{
var viewBox = new Size(pixelsPerModule*this.QrCodeData.ModuleMatrix.Count, pixelsPerModule * this.QrCodeData.ModuleMatrix.Count);
return this.GetGraphic(viewBox, Color.Black, Color.White);
}
public string GetGraphic(int pixelsPerModule, Color darkColor, Color lightColor, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
{
var viewBox = new Size(pixelsPerModule * this.QrCodeData.ModuleMatrix.Count, pixelsPerModule * this.QrCodeData.ModuleMatrix.Count);
return this.GetGraphic(viewBox, darkColor, lightColor, drawQuietZones, sizingMode);
}
public string GetGraphic(int pixelsPerModule, string darkColorHex, string lightColorHex, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
{
var viewBox = new Size(pixelsPerModule * this.QrCodeData.ModuleMatrix.Count, pixelsPerModule * this.QrCodeData.ModuleMatrix.Count);
return this.GetGraphic(viewBox, darkColorHex, lightColorHex, drawQuietZones, sizingMode);
}
public string GetGraphic(Size viewBox, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
{
return this.GetGraphic(viewBox, Color.Black, Color.White, drawQuietZones, sizingMode);
}
public string GetGraphic(Size viewBox, Color darkColor, Color lightColor, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
{
return this.GetGraphic(viewBox, ColorTranslator.ToHtml(Color.FromArgb(darkColor.ToArgb())), ColorTranslator.ToHtml(Color.FromArgb(lightColor.ToArgb())), drawQuietZones, sizingMode);
}
public string GetGraphic(Size viewBox, string darkColorHex, string lightColorHex, bool drawQuietZones = true, SizingMode sizingMode = SizingMode.WidthHeightAttribute)
{
var offset = drawQuietZones ? 0 : 4;
var drawableModulesCount = this.QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : offset * 2);
var pixelsPerModule = (double)Math.Min(viewBox.Width, viewBox.Height) / (double)drawableModulesCount;
var qrSize = drawableModulesCount * pixelsPerModule;
var svgSizeAttributes = sizingMode.Equals(SizingMode.WidthHeightAttribute) ? $@"width=""{viewBox.Width}"" height=""{viewBox.Height}""" : $@"viewBox=""0 0 {viewBox.Width} {viewBox.Height}""";
var svgFile = new StringBuilder($@"<svg version=""1.1"" baseProfile=""full"" shape-rendering=""crispEdges"" {svgSizeAttributes} xmlns=""http://www.w3.org/2000/svg"">");
svgFile.AppendLine($@"<rect x=""0"" y=""0"" width=""{CleanSvgVal(qrSize)}"" height=""{CleanSvgVal(qrSize)}"" fill=""{lightColorHex}"" />");
for (int xi = offset; xi < offset + drawableModulesCount; xi++)
{
for (int yi = offset; yi < offset + drawableModulesCount; yi++)
{
if (this.QrCodeData.ModuleMatrix[yi][xi])
{
var x = (xi - offset) * pixelsPerModule;
var y = (yi - offset) * pixelsPerModule;
svgFile.AppendLine($@"<rect x=""{CleanSvgVal(x)}"" y=""{CleanSvgVal(y)}"" width=""{CleanSvgVal(pixelsPerModule)}"" height=""{CleanSvgVal(pixelsPerModule)}"" fill=""{darkColorHex}"" />");
}
}
}
svgFile.Append(@"</svg>");
return svgFile.ToString();
}
private string CleanSvgVal(double input)
{
//Clean double values for international use/formats
return input.ToString(System.Globalization.CultureInfo.InvariantCulture);
}
public enum SizingMode
{
WidthHeightAttribute,
ViewBoxAttribute
}
}
}
#endif