Skip to content

Commit ae8a58c

Browse files
committed
Upload Horizon source code (v10.1 (Build #22))
1 parent cc5e2e4 commit ae8a58c

File tree

134 files changed

+6816
-11
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

134 files changed

+6816
-11
lines changed

.gitignore

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,6 @@ StyleCopReport.xml
101101
# Chutzpah Test files
102102
_Chutzpah*
103103

104-
# Visual C++ cache files
105-
ipch/
106-
*.aps
107-
*.ncb
108-
*.opendb
109-
*.opensdf
110-
*.sdf
111-
*.cachefile
112-
*.VC.db
113-
*.VC.VC.opendb
114-
115104
# Visual Studio profiler
116105
*.psess
117106
*.vsp

Horizon.slnx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Solution>
2+
<Configurations>
3+
<Platform Name="Any CPU" />
4+
<Platform Name="ARM64" />
5+
<Platform Name="x64" />
6+
<Platform Name="x86" />
7+
</Configurations>
8+
<Project Path="external/QRCoder/QRCoder.csproj" />
9+
<Project Path="package/Horizon.Package/Horizon.Package.wapproj" Type="c7167f0d-bc9f-4e6e-afe1-012c56b48db5" Id="b6778c81-1666-4c6a-90d2-2dffe9002500">
10+
<Deploy />
11+
</Project>
12+
<Project Path="src/Horizon.csproj">
13+
<Platform Solution="*|Any CPU" Project="x64" />
14+
<Platform Solution="*|ARM64" Project="ARM64" />
15+
<Platform Solution="*|x64" Project="x64" />
16+
<Platform Solution="*|x86" Project="x86" />
17+
<Deploy />
18+
</Project>
19+
</Solution>

external/QRCoder/AbstractQRCode.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
namespace QRCoder;
2+
3+
/// <summary>
4+
/// Abstract base class for generating QR codes.
5+
/// Derived classes typically render a QR code into a specific format (png, System.Drawing.Bitmap, PDF, etc).
6+
/// </summary>
7+
public abstract class AbstractQRCode
8+
{
9+
/// <summary>
10+
/// Gets or sets the QRCodeData used to generate the QR code.
11+
/// </summary>
12+
protected QRCodeData QrCodeData { get; set; }
13+
14+
/// <summary>
15+
/// Initializes a new instance of the AbstractQRCode class.
16+
/// </summary>
17+
protected AbstractQRCode()
18+
{
19+
QrCodeData = null!;
20+
}
21+
22+
/// <summary>
23+
/// Initializes a new instance of the AbstractQRCode class with the specified QRCodeData.
24+
/// </summary>
25+
/// <param name="data">The QRCodeData object generated by QRCodeGenerator.CreateQrCode().</param>
26+
protected AbstractQRCode(QRCodeData data)
27+
{
28+
QrCodeData = data;
29+
}
30+
31+
/// <summary>
32+
/// Sets the QRCodeData object that will be used to generate the QR code.
33+
/// This method is useful for COM objects connections.
34+
/// </summary>
35+
/// <param name="data">The QRCodeData object generated by QRCodeGenerator.CreateQrCode().</param>
36+
public virtual void SetQRCodeData(QRCodeData data)
37+
=> QrCodeData = data;
38+
39+
/// <summary>
40+
/// Disposes the QRCodeData object.
41+
/// </summary>
42+
public void Dispose()
43+
{
44+
QrCodeData?.Dispose();
45+
QrCodeData = null!;
46+
}
47+
}

external/QRCoder/BitmapByteQRCode.cs

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
using System;
2+
using static QRCoder.QRCodeGenerator;
3+
4+
namespace QRCoder;
5+
6+
7+
/// <summary>
8+
/// Represents a QR code generator that outputs QR codes as bitmap byte arrays.
9+
/// </summary>
10+
// ReSharper disable once InconsistentNaming
11+
public class BitmapByteQRCode : AbstractQRCode, IDisposable
12+
{
13+
private static readonly byte[] _bitmapHeaderPart1 = new byte[] { 0x42, 0x4D };
14+
private static readonly byte[] _bitmapHeaderPart2 = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00 };
15+
private static readonly byte[] _bitmapHeaderPartEnd = new byte[] { 0x01, 0x00, 0x18, 0x00 };
16+
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="BitmapByteQRCode"/> class.
19+
/// Constructor without parameters to be used in COM objects connections.
20+
/// </summary>
21+
public BitmapByteQRCode() { }
22+
23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="BitmapByteQRCode"/> class with the specified <see cref="QRCodeData"/>.
25+
/// </summary>
26+
/// <param name="data"><see cref="QRCodeData"/> generated by the QRCodeGenerator.</param>
27+
public BitmapByteQRCode(QRCodeData data) : base(data) { }
28+
29+
/// <summary>
30+
/// Returns the QR code graphic as a bitmap byte array.
31+
/// </summary>
32+
/// <param name="pixelsPerModule">The number of pixels each dark/light module of the QR code will occupy in the final QR code image.</param>
33+
/// <returns>Returns the QR code graphic as a bitmap byte array.</returns>
34+
public byte[] GetGraphic(int pixelsPerModule)
35+
=> GetGraphic(pixelsPerModule, new byte[] { 0x00, 0x00, 0x00 }, new byte[] { 0xFF, 0xFF, 0xFF });
36+
37+
/// <summary>
38+
/// Returns the QR code graphic as a bitmap byte array.
39+
/// </summary>
40+
/// <param name="pixelsPerModule">The number of pixels each dark/light module of the QR code will occupy in the final QR code image.</param>
41+
/// <param name="darkColorHtmlHex">The color of the dark modules in HTML hex format.</param>
42+
/// <param name="lightColorHtmlHex">The color of the light modules in HTML hex format.</param>
43+
/// <returns>Returns the QR code graphic as a bitmap byte array.</returns>
44+
public byte[] GetGraphic(int pixelsPerModule, string darkColorHtmlHex, string lightColorHtmlHex)
45+
=> GetGraphic(pixelsPerModule, HexColorToByteArray(darkColorHtmlHex), HexColorToByteArray(lightColorHtmlHex));
46+
47+
/// <summary>
48+
/// Returns the QR code graphic as a bitmap byte array.
49+
/// </summary>
50+
/// <param name="pixelsPerModule">The number of pixels each dark/light module of the QR code will occupy in the final QR code image.</param>
51+
/// <param name="darkColorRgb">The color of the dark modules as an RGB byte array.</param>
52+
/// <param name="lightColorRgb">The color of the light modules as an RGB byte array.</param>
53+
/// <returns>Returns the QR code graphic as a bitmap byte array.</returns>
54+
public byte[] GetGraphic(int pixelsPerModule, byte[] darkColorRgb, byte[] lightColorRgb)
55+
{
56+
var sideLength = QrCodeData.ModuleMatrix.Count * pixelsPerModule;
57+
58+
// Pre-calculate color/module bytes
59+
byte[] moduleDark = new byte[pixelsPerModule * 3];
60+
byte[] moduleLight = new byte[pixelsPerModule * 3];
61+
for (int i = 0; i < pixelsPerModule * 3; i += 3)
62+
{
63+
moduleDark[i] = darkColorRgb[2];
64+
moduleDark[i + 1] = darkColorRgb[1];
65+
moduleDark[i + 2] = darkColorRgb[0];
66+
moduleLight[i] = lightColorRgb[2];
67+
moduleLight[i + 1] = lightColorRgb[1];
68+
moduleLight[i + 2] = lightColorRgb[0];
69+
}
70+
71+
// Pre-calculate padding bytes
72+
var paddingLen = sideLength % 4;
73+
74+
// Calculate filesize (header + pixel data + padding)
75+
var fileSize = 54 + (3 * (sideLength * sideLength)) + (sideLength * paddingLen);
76+
77+
// Bitmap container
78+
byte[] bmp = new byte[fileSize];
79+
int ix = 0;
80+
81+
// Header part 1
82+
Array.Copy(_bitmapHeaderPart1, 0, bmp, ix, _bitmapHeaderPart1.Length);
83+
ix += _bitmapHeaderPart1.Length;
84+
85+
// Filesize
86+
CopyIntAs4ByteToArray(fileSize, ix, bmp);
87+
ix += 4;
88+
89+
// Header part 2
90+
Array.Copy(_bitmapHeaderPart2, 0, bmp, ix, _bitmapHeaderPart2.Length);
91+
ix += _bitmapHeaderPart2.Length;
92+
93+
// Width
94+
CopyIntAs4ByteToArray(sideLength, ix, bmp);
95+
ix += 4;
96+
// Height
97+
CopyIntAs4ByteToArray(sideLength, ix, bmp);
98+
ix += 4;
99+
100+
// Header end
101+
Array.Copy(_bitmapHeaderPartEnd, 0, bmp, ix, _bitmapHeaderPartEnd.Length);
102+
ix += _bitmapHeaderPartEnd.Length;
103+
104+
// Add header null-bytes
105+
ix += 24;
106+
107+
108+
// Draw qr code
109+
for (var x = sideLength - 1; x >= 0; x -= pixelsPerModule)
110+
{
111+
var modMatrixX = (x + pixelsPerModule) / pixelsPerModule - 1;
112+
113+
// Write data for first pixel of pixelsPerModule
114+
int posStartFirstPx = ix;
115+
for (var y = 0; y < sideLength; y += pixelsPerModule)
116+
{
117+
var module = QrCodeData.ModuleMatrix[modMatrixX][(y + pixelsPerModule) / pixelsPerModule - 1];
118+
Array.Copy(module ? moduleDark : moduleLight, 0, bmp, ix, moduleDark.Length);
119+
ix += moduleDark.Length;
120+
}
121+
// Add padding (to make line length a multiple of 4)
122+
ix += paddingLen;
123+
int lenFirstPx = ix - posStartFirstPx;
124+
125+
// Re-write (copy) first pixel (pixelsPerModule - 1) times
126+
for (int pm = 0; pm < (pixelsPerModule - 1); pm++)
127+
{
128+
// Draw pixels
129+
Array.Copy(bmp, posStartFirstPx, bmp, ix, lenFirstPx);
130+
ix += lenFirstPx;
131+
}
132+
}
133+
134+
return bmp;
135+
}
136+
137+
138+
/// <summary>
139+
/// Converts a hex color string to a byte array.
140+
/// </summary>
141+
/// <param name="colorString">The hex color string to convert.</param>
142+
/// <returns>Returns the color as a byte array.</returns>
143+
private byte[] HexColorToByteArray(string colorString)
144+
{
145+
if (colorString.StartsWith("#"))
146+
colorString = colorString.Substring(1);
147+
byte[] byteColor = new byte[colorString.Length / 2];
148+
for (int i = 0; i < byteColor.Length; i++)
149+
byteColor[i] = byte.Parse(colorString.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture);
150+
return byteColor;
151+
}
152+
153+
154+
/// <summary>
155+
/// Converts an integer to a 4 bytes and writes them to a byte array at given position
156+
/// </summary>
157+
/// <param name="inp">The integer to convert.</param>
158+
/// <param name="destinationIndex">Index of destinationArray where the converted bytes are written to</param>
159+
/// <param name="destinationArray">Destination byte array that receives the bytes</param>
160+
private void CopyIntAs4ByteToArray(int inp, int destinationIndex, byte[] destinationArray)
161+
{
162+
unchecked
163+
{
164+
destinationArray[destinationIndex + 3] = (byte)(inp >> 24);
165+
destinationArray[destinationIndex + 2] = (byte)(inp >> 16);
166+
destinationArray[destinationIndex + 1] = (byte)(inp >> 8);
167+
destinationArray[destinationIndex + 0] = (byte)(inp);
168+
}
169+
}
170+
}
171+
172+
173+
/// <summary>
174+
/// Provides helper functions for creating bitmap byte array QR codes.
175+
/// </summary>
176+
public static class BitmapByteQRCodeHelper
177+
{
178+
/// <summary>
179+
/// Creates a bitmap byte array QR code with a single function call.
180+
/// </summary>
181+
/// <param name="plainText">The text or payload to be encoded inside the QR code.</param>
182+
/// <param name="pixelsPerModule">The number of pixels each dark/light module of the QR code will occupy in the final QR code image.</param>
183+
/// <param name="darkColorHtmlHex">The color of the dark modules in HTML hex format.</param>
184+
/// <param name="lightColorHtmlHex">The color of the light modules in HTML hex format.</param>
185+
/// <param name="eccLevel">The level of error correction data.</param>
186+
/// <param name="forceUtf8">Specifies whether the generator should be forced to work in UTF-8 mode.</param>
187+
/// <param name="utf8BOM">Specifies whether the byte-order-mark should be used.</param>
188+
/// <param name="eciMode">Specifies which ECI mode should be used.</param>
189+
/// <param name="requestedVersion">Sets the fixed QR code target version.</param>
190+
/// <returns>Returns the QR code graphic as a bitmap byte array.</returns>
191+
public static byte[] GetQRCode(string plainText, int pixelsPerModule, string darkColorHtmlHex,
192+
string lightColorHtmlHex, ECCLevel eccLevel, bool forceUtf8 = false, bool utf8BOM = false,
193+
EciMode eciMode = EciMode.Default, int requestedVersion = -1)
194+
{
195+
using var qrGenerator = new QRCodeGenerator();
196+
using var qrCodeData = qrGenerator.CreateQrCode(plainText, eccLevel, forceUtf8, utf8BOM, eciMode,
197+
requestedVersion);
198+
using var qrCode = new BitmapByteQRCode(qrCodeData);
199+
return qrCode.GetGraphic(pixelsPerModule, darkColorHtmlHex, lightColorHtmlHex);
200+
}
201+
202+
/// <summary>
203+
/// Creates a bitmap byte array QR code with a single function call.
204+
/// </summary>
205+
/// <param name="txt">The text or payload to be encoded inside the QR code.</param>
206+
/// <param name="eccLevel">The level of error correction data.</param>
207+
/// <param name="size">The number of pixels each dark/light module of the QR code will occupy in the final QR code image.</param>
208+
/// <returns>Returns the QR code graphic as a bitmap byte array.</returns>
209+
public static byte[] GetQRCode(string txt, QRCodeGenerator.ECCLevel eccLevel, int size)
210+
{
211+
using var qrGen = new QRCodeGenerator();
212+
using var qrCode = qrGen.CreateQrCode(txt, eccLevel);
213+
using var qrBmp = new BitmapByteQRCode(qrCode);
214+
return qrBmp.GetGraphic(size);
215+
216+
}
217+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
3+
namespace QRCoder.Exceptions;
4+
5+
/// <summary>
6+
/// Exception thrown when the given payload exceeds the maximum size of the QR code standard.
7+
/// </summary>
8+
public class DataTooLongException : Exception
9+
{
10+
/// <summary>
11+
/// Initializes a new instance of the <see cref="DataTooLongException"/> class with a specified error message.
12+
/// </summary>
13+
/// <param name="eccLevel">The error correction level of the QR code.</param>
14+
/// <param name="encodingMode">The encoding mode of the QR code.</param>
15+
/// <param name="maxSizeByte">The maximum size allowed for the given parameters in bytes.</param>
16+
public DataTooLongException(string eccLevel, string encodingMode, int maxSizeByte) : base(
17+
$"The given payload exceeds the maximum size of the QR code standard. The maximum size allowed for the chosen parameters (ECC level={eccLevel}, EncodingMode={encodingMode}) is {maxSizeByte} bytes."
18+
)
19+
{ }
20+
21+
/// <summary>
22+
/// Initializes a new instance of the <see cref="DataTooLongException"/> class with a specified error message.
23+
/// </summary>
24+
/// <param name="eccLevel">The error correction level of the QR code.</param>
25+
/// <param name="encodingMode">The encoding mode of the QR code.</param>
26+
/// <param name="version">The fixed version of the QR code.</param>
27+
/// <param name="maxSizeByte">The maximum size allowed for the given parameters in bytes.</param>
28+
public DataTooLongException(string eccLevel, string encodingMode, int version, int maxSizeByte) : base(
29+
$"The given payload exceeds the maximum size of the QR code standard. The maximum size allowed for the chosen parameters (ECC level={eccLevel}, EncodingMode={encodingMode}, FixedVersion={version}) is {maxSizeByte} bytes."
30+
)
31+
{ }
32+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Collections;
2+
3+
namespace QRCoder;
4+
5+
/// <summary>
6+
/// Helper methods for <see cref="BitArray"/>.
7+
/// </summary>
8+
internal static class BitArrayExtensions
9+
{
10+
/// <summary>
11+
/// Copies a specified number of elements from one <see cref="BitArray"/> to another starting at the specified offsets.
12+
/// </summary>
13+
/// <param name="source">The source <see cref="BitArray"/> from which elements will be copied.</param>
14+
/// <param name="sourceOffset">The zero-based index in the source <see cref="BitArray"/> at which copying begins.</param>
15+
/// <param name="destination">The destination <see cref="BitArray"/> to which elements will be copied.</param>
16+
/// <param name="destinationOffset">The zero-based index in the destination <see cref="BitArray"/> at which storing begins.</param>
17+
/// <param name="count">The number of elements to copy.</param>
18+
/// <returns>The index in the destination <see cref="BitArray"/> immediately following the last copied element.</returns>
19+
public static int CopyTo(this BitArray source, BitArray destination, int sourceOffset, int destinationOffset, int count)
20+
{
21+
for (int i = 0; i < count; i++)
22+
{
23+
destination[destinationOffset + i] = source[sourceOffset + i];
24+
}
25+
return destinationOffset + count;
26+
}
27+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
namespace QRCoder;
2+
3+
/// <summary>
4+
/// Contains classes and methods for generating payloads for QR codes.
5+
/// </summary>
6+
public static partial class PayloadGenerator
7+
{
8+
/// <summary>
9+
/// Represents the base class for all QR code payloads.
10+
/// </summary>
11+
public abstract class Payload
12+
{
13+
/// <summary>
14+
/// Gets the version of the QR code payload.
15+
/// </summary>
16+
public virtual int Version => -1;
17+
18+
/// <summary>
19+
/// Gets the error correction level of the QR code payload.
20+
/// </summary>
21+
public virtual QRCodeGenerator.ECCLevel EccLevel => QRCodeGenerator.ECCLevel.Default;
22+
23+
/// <summary>
24+
/// Gets the ECI mode of the QR code payload.
25+
/// </summary>
26+
public virtual QRCodeGenerator.EciMode EciMode => QRCodeGenerator.EciMode.Default;
27+
28+
/// <summary>
29+
/// Returns a string representation of the QR code payload.
30+
/// </summary>
31+
/// <returns>A string representation of the QR code payload.</returns>
32+
public abstract override string ToString();
33+
}
34+
}

0 commit comments

Comments
 (0)