Add BlockMap media graph.

This commit is contained in:
2022-12-05 21:28:43 +00:00
parent 87ccb3cf1d
commit 511b97ec22
2 changed files with 405 additions and 123 deletions

View File

@@ -34,8 +34,8 @@
<NoWarn>CS1591;CS1574</NoWarn>
</PropertyGroup>
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<InternalsVisibleTo Include="Aaru.Tests"/>
<InternalsVisibleTo Include="Aaru.Tests.Devices"/>
<InternalsVisibleTo Include="Aaru.Tests" />
<InternalsVisibleTo Include="Aaru.Tests.Devices" />
</ItemGroup>
<PropertyGroup>
<NrtRevisionFormat>$(Version)+{chash:8}</NrtRevisionFormat>
@@ -43,121 +43,122 @@
<NrtShowRevision>true</NrtShowRevision>
</PropertyGroup>
<ItemGroup>
<Compile Include="Devices\Dumping\CompactDisc\CdiReady.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Data.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Dump.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Error.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\LeadOuts.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Offset.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Plextor.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Pregap.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Recordable.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Subchannel.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Tags.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Tracks.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\Trim.cs"/>
<Compile Include="Devices\Dumping\Dump.cs"/>
<Compile Include="Devices\Dumping\LinearMemory\Retrode.cs"/>
<Compile Include="Devices\Dumping\Metadata.cs"/>
<Compile Include="Devices\Dumping\MiniDisc.cs"/>
<Compile Include="Devices\Dumping\PlayStationPortable\MemoryStick.cs"/>
<Compile Include="Devices\Dumping\PlayStationPortable\PlayStationPortable.cs"/>
<Compile Include="Devices\Dumping\PlayStationPortable\UMD.cs"/>
<Compile Include="Devices\Dumping\Sbc\Data.cs"/>
<Compile Include="Devices\Dumping\Sbc\Error.cs"/>
<Compile Include="Devices\Dumping\Sbc\Dump.cs"/>
<Compile Include="Devices\Dumping\Sbc\Optical.cs"/>
<Compile Include="Devices\Dumping\Sbc\Trim.cs"/>
<Compile Include="Devices\Info\DeviceInfo.cs"/>
<Compile Include="Devices\Info\Plextor.cs"/>
<Compile Include="Devices\Info\Properties.cs"/>
<Compile Include="Devices\Report\DeviceReport.cs"/>
<Compile Include="Devices\Report\GdRomSwapTrick.cs"/>
<Compile Include="Devices\Report\Scsi.cs"/>
<Compile Include="Devices\Report\MMC.cs"/>
<Compile Include="Devices\Report\SSC.cs"/>
<Compile Include="Devices\Scanning\MediaScan.cs"/>
<Compile Include="Entropy.cs"/>
<Compile Include="GetPluginBase.cs"/>
<Compile Include="Graphics\Spiral.cs"/>
<Compile Include="ImageInfo.cs"/>
<Compile Include="Logging\ErrorLog.cs"/>
<Compile Include="Logging\SubchannelLog.cs"/>
<Compile Include="Media\CompactDisc.cs"/>
<Compile Include="Media\Detection\MMC.cs"/>
<Compile Include="Media\Info\CompactDisc.cs"/>
<Compile Include="Media\Info\ScsiInfo.cs"/>
<Compile Include="Media\Info\XgdInfo.cs"/>
<Compile Include="Options.cs"/>
<Compile Include="ImageFormat.cs"/>
<Compile Include="Error.cs"/>
<Compile Include="PrintScsiModePages.cs"/>
<Compile Include="Sidecar\Files.cs"/>
<Compile Include="Spectre.cs"/>
<Compile Include="Statistics.cs"/>
<Compile Include="Checksum.cs"/>
<Compile Include="Logging\IBGLog.cs"/>
<Compile Include="Logging\MHDDLog.cs"/>
<Compile Include="Devices\Scanning\ATA.cs"/>
<Compile Include="Devices\Scanning\SecureDigital.cs"/>
<Compile Include="Devices\Scanning\NVMe.cs"/>
<Compile Include="Devices\Scanning\SCSI.cs"/>
<Compile Include="Devices\Dumping\ATA.cs"/>
<Compile Include="Devices\Dumping\NVMe.cs"/>
<Compile Include="Devices\Dumping\SCSI.cs"/>
<Compile Include="Devices\Dumping\SecureDigital.cs"/>
<Compile Include="DataFile.cs"/>
<Compile Include="Filesystems.cs"/>
<Compile Include="Devices\Scanning\ScanResults.cs"/>
<Compile Include="Devices\Report\ATA.cs"/>
<Compile Include="Devices\Report\FireWire.cs"/>
<Compile Include="Devices\Report\USB.cs"/>
<Compile Include="Devices\Report\SecureDigital.cs"/>
<Compile Include="Remote.cs"/>
<Compile Include="Devices\Report\PCMCIA.cs"/>
<Compile Include="Devices\Reader.cs"/>
<Compile Include="Devices\ReaderATA.cs"/>
<Compile Include="Devices\ReaderSCSI.cs"/>
<Compile Include="Devices\Dumping\SSC.cs"/>
<Compile Include="Devices\Dumping\MMC.cs"/>
<Compile Include="Devices\Dumping\XGD.cs"/>
<Compile Include="Devices\Dumping\ResumeSupport.cs"/>
<Compile Include="Partitions.cs"/>
<Compile Include="Sidecar\Events.cs"/>
<Compile Include="Sidecar\Helpers.cs"/>
<Compile Include="Sidecar\Sidecar.cs"/>
<Compile Include="Sidecar\OpticalDisc.cs"/>
<Compile Include="Sidecar\BlockMedia.cs"/>
<Compile Include="Sidecar\LinearMedia.cs"/>
<Compile Include="Sidecar\AudioMedia.cs"/>
<Compile Include="Sidecar\BlockTape.cs"/>
<Compile Include="Logging\DumpLog.cs"/>
<Compile Include="Devices\Dumping\CompactDisc\CdiReady.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Data.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Dump.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Error.cs" />
<Compile Include="Devices\Dumping\CompactDisc\LeadOuts.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Offset.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Plextor.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Pregap.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Recordable.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Subchannel.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Tags.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Tracks.cs" />
<Compile Include="Devices\Dumping\CompactDisc\Trim.cs" />
<Compile Include="Devices\Dumping\Dump.cs" />
<Compile Include="Devices\Dumping\LinearMemory\Retrode.cs" />
<Compile Include="Devices\Dumping\Metadata.cs" />
<Compile Include="Devices\Dumping\MiniDisc.cs" />
<Compile Include="Devices\Dumping\PlayStationPortable\MemoryStick.cs" />
<Compile Include="Devices\Dumping\PlayStationPortable\PlayStationPortable.cs" />
<Compile Include="Devices\Dumping\PlayStationPortable\UMD.cs" />
<Compile Include="Devices\Dumping\Sbc\Data.cs" />
<Compile Include="Devices\Dumping\Sbc\Error.cs" />
<Compile Include="Devices\Dumping\Sbc\Dump.cs" />
<Compile Include="Devices\Dumping\Sbc\Optical.cs" />
<Compile Include="Devices\Dumping\Sbc\Trim.cs" />
<Compile Include="Devices\Info\DeviceInfo.cs" />
<Compile Include="Devices\Info\Plextor.cs" />
<Compile Include="Devices\Info\Properties.cs" />
<Compile Include="Devices\Report\DeviceReport.cs" />
<Compile Include="Devices\Report\GdRomSwapTrick.cs" />
<Compile Include="Devices\Report\Scsi.cs" />
<Compile Include="Devices\Report\MMC.cs" />
<Compile Include="Devices\Report\SSC.cs" />
<Compile Include="Devices\Scanning\MediaScan.cs" />
<Compile Include="Entropy.cs" />
<Compile Include="GetPluginBase.cs" />
<Compile Include="Graphics\BlockMap.cs" />
<Compile Include="Graphics\Spiral.cs" />
<Compile Include="ImageInfo.cs" />
<Compile Include="Logging\ErrorLog.cs" />
<Compile Include="Logging\SubchannelLog.cs" />
<Compile Include="Media\CompactDisc.cs" />
<Compile Include="Media\Detection\MMC.cs" />
<Compile Include="Media\Info\CompactDisc.cs" />
<Compile Include="Media\Info\ScsiInfo.cs" />
<Compile Include="Media\Info\XgdInfo.cs" />
<Compile Include="Options.cs" />
<Compile Include="ImageFormat.cs" />
<Compile Include="Error.cs" />
<Compile Include="PrintScsiModePages.cs" />
<Compile Include="Sidecar\Files.cs" />
<Compile Include="Spectre.cs" />
<Compile Include="Statistics.cs" />
<Compile Include="Checksum.cs" />
<Compile Include="Logging\IBGLog.cs" />
<Compile Include="Logging\MHDDLog.cs" />
<Compile Include="Devices\Scanning\ATA.cs" />
<Compile Include="Devices\Scanning\SecureDigital.cs" />
<Compile Include="Devices\Scanning\NVMe.cs" />
<Compile Include="Devices\Scanning\SCSI.cs" />
<Compile Include="Devices\Dumping\ATA.cs" />
<Compile Include="Devices\Dumping\NVMe.cs" />
<Compile Include="Devices\Dumping\SCSI.cs" />
<Compile Include="Devices\Dumping\SecureDigital.cs" />
<Compile Include="DataFile.cs" />
<Compile Include="Filesystems.cs" />
<Compile Include="Devices\Scanning\ScanResults.cs" />
<Compile Include="Devices\Report\ATA.cs" />
<Compile Include="Devices\Report\FireWire.cs" />
<Compile Include="Devices\Report\USB.cs" />
<Compile Include="Devices\Report\SecureDigital.cs" />
<Compile Include="Remote.cs" />
<Compile Include="Devices\Report\PCMCIA.cs" />
<Compile Include="Devices\Reader.cs" />
<Compile Include="Devices\ReaderATA.cs" />
<Compile Include="Devices\ReaderSCSI.cs" />
<Compile Include="Devices\Dumping\SSC.cs" />
<Compile Include="Devices\Dumping\MMC.cs" />
<Compile Include="Devices\Dumping\XGD.cs" />
<Compile Include="Devices\Dumping\ResumeSupport.cs" />
<Compile Include="Partitions.cs" />
<Compile Include="Sidecar\Events.cs" />
<Compile Include="Sidecar\Helpers.cs" />
<Compile Include="Sidecar\Sidecar.cs" />
<Compile Include="Sidecar\OpticalDisc.cs" />
<Compile Include="Sidecar\BlockMedia.cs" />
<Compile Include="Sidecar\LinearMedia.cs" />
<Compile Include="Sidecar\AudioMedia.cs" />
<Compile Include="Sidecar\BlockTape.cs" />
<Compile Include="Logging\DumpLog.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Aaru.Archives\Aaru.Archives.csproj"/>
<ProjectReference Include="..\Aaru.Console\Aaru.Console.csproj"/>
<ProjectReference Include="..\Aaru.Database\Aaru.Database.csproj"/>
<ProjectReference Include="..\Aaru.Decryption\Aaru.Decryption.csproj"/>
<ProjectReference Include="..\Aaru.Dto\Aaru.Dto.csproj"/>
<ProjectReference Include="..\Aaru.Filesystems\Aaru.Filesystems.csproj"/>
<ProjectReference Include="..\Aaru.Localization\Aaru.Localization.csproj"/>
<ProjectReference Include="..\Aaru.Partitions\Aaru.Partitions.csproj"/>
<ProjectReference Include="..\Aaru.Images\Aaru.Images.csproj"/>
<ProjectReference Include="..\Aaru.Filters\Aaru.Filters.csproj"/>
<ProjectReference Include="..\Aaru.Settings\Aaru.Settings.csproj"/>
<ProjectReference Include="..\Aaru.Devices\Aaru.Devices.csproj"/>
<ProjectReference Include="..\Aaru.CommonTypes\Aaru.CommonTypes.csproj"/>
<ProjectReference Include="..\Aaru.Checksums\Aaru.Checksums.csproj"/>
<ProjectReference Include="..\Aaru.Decoders\Aaru.Decoders.csproj"/>
<ProjectReference Include="..\Aaru.Helpers\Aaru.Helpers.csproj"/>
<ProjectReference Include="..\Aaru.Archives\Aaru.Archives.csproj" />
<ProjectReference Include="..\Aaru.Console\Aaru.Console.csproj" />
<ProjectReference Include="..\Aaru.Database\Aaru.Database.csproj" />
<ProjectReference Include="..\Aaru.Decryption\Aaru.Decryption.csproj" />
<ProjectReference Include="..\Aaru.Dto\Aaru.Dto.csproj" />
<ProjectReference Include="..\Aaru.Filesystems\Aaru.Filesystems.csproj" />
<ProjectReference Include="..\Aaru.Localization\Aaru.Localization.csproj" />
<ProjectReference Include="..\Aaru.Partitions\Aaru.Partitions.csproj" />
<ProjectReference Include="..\Aaru.Images\Aaru.Images.csproj" />
<ProjectReference Include="..\Aaru.Filters\Aaru.Filters.csproj" />
<ProjectReference Include="..\Aaru.Settings\Aaru.Settings.csproj" />
<ProjectReference Include="..\Aaru.Devices\Aaru.Devices.csproj" />
<ProjectReference Include="..\Aaru.CommonTypes\Aaru.CommonTypes.csproj" />
<ProjectReference Include="..\Aaru.Checksums\Aaru.Checksums.csproj" />
<ProjectReference Include="..\Aaru.Decoders\Aaru.Decoders.csproj" />
<ProjectReference Include="..\Aaru.Helpers\Aaru.Helpers.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Logging\"/>
<Folder Include="Devices\"/>
<Folder Include="Devices\Scanning\"/>
<Folder Include="Devices\Dumping\"/>
<Folder Include="Devices\Report\"/>
<Folder Include="Sidecar\"/>
<Folder Include="Logging\" />
<Folder Include="Devices\" />
<Folder Include="Devices\Scanning\" />
<Folder Include="Devices\Dumping\" />
<Folder Include="Devices\Report\" />
<Folder Include="Sidecar\" />
</ItemGroup>
<ItemGroup>
<Content Include="..\LICENSE">
@@ -165,15 +166,15 @@
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="SkiaSharp" Version="2.88.3"/>
<PackageReference Include="Spectre.Console" Version="0.45.0"/>
<PackageReference Include="System.ValueTuple" Version="4.5.0"/>
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3" PrivateAssets="all"/>
<PackageReference Include="System.Collections" Version="4.3.0"/>
<PackageReference Include="System.Diagnostics.Debug" Version="4.3.0"/>
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0"/>
<PackageReference Include="System.Runtime.Extensions" Version="4.3.1"/>
<PackageReference Include="System.Runtime.Handles" Version="4.3.0"/>
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0"/>
<PackageReference Include="SkiaSharp" Version="2.88.3" />
<PackageReference Include="Spectre.Console" Version="0.45.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3" PrivateAssets="all" />
<PackageReference Include="System.Collections" Version="4.3.0" />
<PackageReference Include="System.Diagnostics.Debug" Version="4.3.0" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="System.Runtime.Extensions" Version="4.3.1" />
<PackageReference Include="System.Runtime.Handles" Version="4.3.0" />
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,281 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : BlockMap.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Core algorithms.
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General public License for more details.
//
// You should have received a copy of the GNU General public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2023 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Aaru.CommonTypes.Interfaces;
using SkiaSharp;
namespace Aaru.Core.Graphics;
public class BlockMap : IMediaGraph
{
readonly SKBitmap _bitmap;
readonly SKCanvas _canvas;
readonly int _columns;
readonly int _sectorsPerSquare;
readonly int _squareSize;
public BlockMap(int width, int height, ulong maxSectors)
{
_squareSize = 8;
_columns = (width - 1) / (_squareSize + 1);
int rows = (height - 1) / (_squareSize + 1);
int squares = _columns * rows;
// Check if we can get bigger squares
while(squares - _columns > (long)maxSectors)
{
_squareSize++;
_columns = (width - 1) / (_squareSize + 1);
rows = (height - 1) / (_squareSize + 1);
squares = _columns * rows;
}
_sectorsPerSquare = (int)((long)maxSectors / squares);
while(_sectorsPerSquare > 0 &&
_squareSize > 4)
{
_squareSize--;
_columns = (width - 1) / (_squareSize + 1);
rows = (height - 1) / (_squareSize + 1);
squares = _columns * rows;
_sectorsPerSquare = (int)((long)maxSectors / squares);
}
int removeSquaresAtLastRow = 0;
int removeRows = 0;
// If we have spare squares, remove them
if(squares > (long)maxSectors)
{
int removeSquares = (int)(squares - (long)maxSectors);
removeRows = removeSquares / _columns;
removeSquaresAtLastRow = removeSquares % _columns;
}
float w = (_columns * (_squareSize + 1)) + 1;
float h = (rows * (_squareSize + 1)) + 1;
_bitmap = new SKBitmap((int)w, (int)h);
_canvas = new SKCanvas(_bitmap);
// Paint background white
_canvas.DrawRect(0, 0, w, h, new SKPaint
{
Style = SKPaintStyle.StrokeAndFill,
Color = SKColors.White
});
// Paint undumped sectors
_canvas.DrawRect(0, 0, w, h - (removeRows * (_squareSize + 1)) - _squareSize - 2, new SKPaint
{
Style = SKPaintStyle.StrokeAndFill,
Color = SKColors.Gray
});
_canvas.DrawRect(0, h - (removeRows * (_squareSize + 1)) - _squareSize - 2,
(_columns - removeSquaresAtLastRow) * (_squareSize + 1), _squareSize + 2, new SKPaint
{
Style = SKPaintStyle.StrokeAndFill,
Color = SKColors.Gray
});
// Draw grid
for(float y = 0; y < h - (removeRows * (_squareSize + 1)); y += _squareSize + 1)
{
if(y > h - (removeRows * (_squareSize + 1)) - (_squareSize + 2))
{
int cw = _columns - removeSquaresAtLastRow;
_canvas.DrawLine(0f, y, cw * (_squareSize + 1), y, new SKPaint
{
StrokeWidth = 1f,
Color = SKColors.Black
});
}
else
_canvas.DrawLine(0f, y, w, y, new SKPaint
{
StrokeWidth = 1f,
Color = SKColors.Black
});
}
for(float x = 0; x < w; x += _squareSize + 1)
{
float currentColumn = x / (_squareSize + 1);
if(_columns - currentColumn + 1 > removeSquaresAtLastRow)
_canvas.DrawLine(x, 0, x, h - (removeRows * (_squareSize + 1)), new SKPaint
{
StrokeWidth = 1f,
Color = SKColors.Black
});
else
_canvas.DrawLine(x, 0, x, h - (removeRows * (_squareSize + 1)) - _squareSize - 2, new SKPaint
{
StrokeWidth = 1f,
Color = SKColors.Black
});
}
}
/// <inheritdoc />
public void PaintSectorGood(ulong sector) => PaintSector(sector, SKColors.Green);
/// <inheritdoc />
public void PaintSectorBad(ulong sector) => PaintSector(sector, SKColors.Red);
/// <inheritdoc />
public void PaintSectorUnknown(ulong sector) => PaintSector(sector, SKColors.Yellow);
/// <inheritdoc />
public void PaintSectorUndumped(ulong sector) => PaintSector(sector, SKColors.Gray);
/// <inheritdoc />
public void PaintSector(ulong sector, byte red, byte green, byte blue, byte opacity = 255) =>
PaintSector(sector, new SKColor(red, green, blue, opacity));
/// <inheritdoc />
public void PaintSectorsUndumped(ulong startingSector, uint length) =>
PaintSectors(startingSector, length, SKColors.Gray);
/// <inheritdoc />
public void PaintSectorsGood(ulong startingSector, uint length) =>
PaintSectors(startingSector, length, SKColors.Green);
/// <inheritdoc />
public void PaintSectorsBad(ulong startingSector, uint length) =>
PaintSectors(startingSector, length, SKColors.Red);
/// <inheritdoc />
public void PaintSectorsUnknown(ulong startingSector, uint length) =>
PaintSectors(startingSector, length, SKColors.Yellow);
/// <inheritdoc />
public void PaintSectors(ulong startingSector, uint length, byte red, byte green, byte blue, byte opacity = 255) =>
PaintSectors(startingSector, length, new SKColor(red, green, blue, opacity));
/// <inheritdoc />
public void PaintSectorsUndumped(IEnumerable<ulong> sectors) => PaintSectors(sectors, SKColors.Gray);
/// <inheritdoc />
public void PaintSectorsGood(IEnumerable<ulong> sectors) => PaintSectors(sectors, SKColors.Green);
/// <inheritdoc />
public void PaintSectorsBad(IEnumerable<ulong> sectors) => PaintSectors(sectors, SKColors.Red);
/// <inheritdoc />
public void PaintSectorsUnknown(IEnumerable<ulong> sectors) => PaintSectors(sectors, SKColors.Yellow);
/// <inheritdoc />
public void PaintSectorsUnknown(IEnumerable<ulong> sectors, byte red, byte green, byte blue, byte opacity = 255) =>
PaintSectors(sectors, new SKColor(red, green, blue, opacity));
/// <inheritdoc />
public void PaintRecordableInformationGood()
{
// Do nothing
}
/// <inheritdoc />
public void WriteTo(Stream stream)
{
var image = SKImage.FromBitmap(_bitmap);
SKData data = image.Encode();
data.SaveTo(stream);
}
/// <inheritdoc />
public void WriteTo(string path)
{
using var fs = new FileStream(path, FileMode.Create);
WriteTo(fs);
fs.Close();
}
void PaintSector(ulong sector, SKColor color)
{
SKRect rect =
GetSquareRectangle(_sectorsPerSquare == 0 ? (int)sector : (int)(sector / (ulong)_sectorsPerSquare));
_canvas.DrawRect(rect, new SKPaint
{
Style = SKPaintStyle.StrokeAndFill,
Color = color
});
}
void PaintSectors(ulong startingSector, uint length, SKColor color)
{
for(ulong sector = startingSector; sector < startingSector + length; sector++)
{
SKRect rect =
GetSquareRectangle(_sectorsPerSquare == 0 ? (int)sector : (int)(sector / (ulong)_sectorsPerSquare));
_canvas.DrawRect(rect, new SKPaint
{
Style = SKPaintStyle.StrokeAndFill,
Color = color
});
}
}
void PaintSectors(IEnumerable<ulong> sectors, SKColor color)
{
foreach(SKRect rect in sectors.Select(sector => GetSquareRectangle(_sectorsPerSquare == 0 ? (int)sector
: (int)
(sector / (ulong)_sectorsPerSquare))))
{
_canvas.DrawRect(rect, new SKPaint
{
Style = SKPaintStyle.StrokeAndFill,
Color = color
});
}
}
SKRect GetSquareRectangle(int square)
{
int row = square / _columns;
int column = square % _columns;
float x = 1 + (column * (_squareSize + 1));
float y = 1 + (row * (_squareSize + 1));
float xp = x + _squareSize;
float yp = y + _squareSize;
return new SKRect(x, y, xp, yp);
}
}