Skip to content

Commit

Permalink
Merge pull request #530 from Shane32/speed2
Browse files Browse the repository at this point in the history
Refactor and optimize BlockedModules
  • Loading branch information
codebude authored May 22, 2024
2 parents 14a83f2 + a8d492c commit 8259416
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 113 deletions.
11 changes: 10 additions & 1 deletion QRCoder/QRCodeData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,16 @@ public QRCodeData(int version)
{
this.Version = version;
var size = ModulesPerSideFromVersion(version);
this.ModuleMatrix = new List<BitArray>();
this.ModuleMatrix = new List<BitArray>(size);
for (var i = 0; i < size; i++)
this.ModuleMatrix.Add(new BitArray(size));
}

public QRCodeData(int version, bool addPadding)
{
this.Version = version;
var size = ModulesPerSideFromVersion(version) + (addPadding ? 8 : 0);
this.ModuleMatrix = new List<BitArray>(size);
for (var i = 0; i < size; i++)
this.ModuleMatrix.Add(new BitArray(size));
}
Expand Down
101 changes: 101 additions & 0 deletions QRCoder/QRCodeGenerator.ModulePlacer.BlockedModules.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using System;
using System.Collections;
using System.Threading;

namespace QRCoder
{
public partial class QRCodeGenerator
{
private static partial class ModulePlacer
{
/// <summary>
/// Struct that represents blocked modules using rectangles.
/// </summary>
public struct BlockedModules : IDisposable
{
private readonly BitArray[] _blockedModules;

private static BitArray[] _staticBlockedModules;

/// <summary>
/// Initializes a new instance of the <see cref="BlockedModules"/> struct with a specified capacity.
/// </summary>
/// <param name="capacity">The initial capacity of the blocked modules list.</param>
public BlockedModules(int size)
{
_blockedModules = Interlocked.Exchange(ref _staticBlockedModules, null);
if (_blockedModules != null && _blockedModules.Length >= size)
{
for (int i = 0; i < size; i++)
_blockedModules[i].SetAll(false);
}
else
{
_blockedModules = new BitArray[size];
for (int i = 0; i < size; i++)
_blockedModules[i] = new BitArray(size);
}
}

/// <summary>
/// Adds a blocked module at the specified coordinates.
/// </summary>
/// <param name="x">The x-coordinate of the module.</param>
/// <param name="y">The y-coordinate of the module.</param>
public void Add(int x, int y)
{
_blockedModules[y][x] = true;
}

/// <summary>
/// Adds a blocked module defined by the specified rectangle.
/// </summary>
/// <param name="rect">The rectangle that defines the blocked module.</param>
public void Add(Rectangle rect)
{
for (int y = rect.Y; y < rect.Y + rect.Height; y++)
{
for (int x = rect.X; x < rect.X + rect.Width; x++)
{
_blockedModules[y][x] = true;
}
}
}

/// <summary>
/// Checks if the specified coordinates are blocked.
/// </summary>
/// <param name="x">The x-coordinate to check.</param>
/// <param name="y">The y-coordinate to check.</param>
/// <returns><c>true</c> if the coordinates are blocked; otherwise, <c>false</c>.</returns>
public bool IsBlocked(int x, int y)
{
return _blockedModules[y][x];
}

/// <summary>
/// Checks if the specified rectangle is blocked.
/// </summary>
/// <param name="r1">The rectangle to check.</param>
/// <returns><c>true</c> if the rectangle is blocked; otherwise, <c>false</c>.</returns>
public bool IsBlocked(Rectangle r1)
{
for (int y = r1.Y; y < r1.Y + r1.Height; y++)
{
for (int x = r1.X; x < r1.X + r1.Width; x++)
{
if (_blockedModules[y][x])
return true;
}
}
return false;
}

public void Dispose()
{
Interlocked.CompareExchange(ref _staticBlockedModules, _blockedModules, null);
}
}
}
}
}
Loading

0 comments on commit 8259416

Please sign in to comment.