Skip to content

Commit

Permalink
Fixing filled drawing
Browse files Browse the repository at this point in the history
  • Loading branch information
maxim-zhao committed Jun 26, 2024
1 parent 44c8e11 commit dd915d1
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 28 deletions.
2 changes: 0 additions & 2 deletions LibSidWiz/SampleBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace LibSidWiz
{
internal class SampleBuffer: IDisposable
{
private readonly string _filename;
private readonly WaveStream _reader;
private readonly ISampleProvider _sampleProvider;

Expand Down Expand Up @@ -49,7 +48,6 @@ public bool TryGet(long index, out float value)

public SampleBuffer(string filename, Channel.Sides side, bool filter)
{
_filename = filename;
_reader = new AudioFileReader(filename);
Count = _reader.Length * 8 / _reader.WaveFormat.BitsPerSample / _reader.WaveFormat.Channels;
SampleRate = _reader.WaveFormat.SampleRate;
Expand Down
39 changes: 22 additions & 17 deletions LibSidWiz/WaveformRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ private void Render(int startFrame, int endFrame, Action<SKImage, byte[]> onFram
var innerPinnedArray = GCHandle.Alloc(rawData, GCHandleType.Pinned);

// Prepare the pens and brushes we will use
var pens = _channels.Select(c => c.LineColor == Color.Transparent || c.LineWidth <= 0
var linePaints = _channels.Select(c => c.LineColor == Color.Transparent || c.LineWidth <= 0
? null
: new SKPaint {
Color = new SKColor(c.LineColor.R, c.LineColor.G, c.LineColor.B, c.LineColor.A),
Expand All @@ -173,10 +173,10 @@ private void Render(int startFrame, int endFrame, Action<SKImage, byte[]> onFram
StrokeMiter = c.LineWidth,
StrokeJoin = SKStrokeJoin.Bevel
}).ToList();
var brushes = _channels.Select(c => c.FillColor == Color.Transparent
var fillPaints = _channels.Select(c => c.FillColor == Color.Transparent
? null
: new SKPaint {
Color = new SKColor(c.LineColor.R, c.LineColor.G, c.LineColor.B, c.LineColor.A),
Color = new SKColor(c.FillColor.R, c.FillColor.G, c.FillColor.B, c.FillColor.A),
StrokeWidth = c.LineWidth,
IsAntialias = c.SmoothLines,
Style = SKPaintStyle.Fill,
Expand All @@ -191,8 +191,8 @@ private void Render(int startFrame, int endFrame, Action<SKImage, byte[]> onFram
using var surface = SKSurface.Create(pixmap.Info, innerPinnedArray.AddrOfPinnedObject());

// Prepare buffers to hold the line coordinates
var points = _channels.Select(channel => new PointF[channel.ViewWidthInSamples]).ToList();
var path = new SKPath();
var fillPath = new SKPath();

while (!queue.IsCompleted)
{
Expand Down Expand Up @@ -234,8 +234,7 @@ private void Render(int startFrame, int endFrame, Action<SKImage, byte[]> onFram
else
// ReSharper disable once AccessToDisposedClosure
RenderWave(g, channel, frame.ChannelTriggerPoints[channelIndex],
pens[channelIndex], brushes[channelIndex],
points[channelIndex], path, channel.FillBase);
linePaints[channelIndex], fillPaints[channelIndex], path, fillPath, channel.FillBase);
}

// We "lend" the data to the frame info temporarily
Expand All @@ -251,12 +250,12 @@ private void Render(int startFrame, int endFrame, Action<SKImage, byte[]> onFram
finally
{
innerPinnedArray.Free();
foreach (var pen in pens)
foreach (var pen in linePaints)
{
pen?.Dispose();
}

foreach (var brush in brushes)
foreach (var brush in fillPaints)
{
brush?.Dispose();
}
Expand Down Expand Up @@ -445,7 +444,8 @@ private void GenerateTemplate(Image template)
}
}

private void RenderWave(SKCanvas g, Channel channel, int triggerPoint, SKPaint linePaint, SKPaint fillPaint, PointF[] points, SKPath path, double fillBase)
private static void RenderWave(SKCanvas g, Channel channel, int triggerPoint, SKPaint linePaint,
SKPaint fillPaint, SKPath path, SKPath fillPath, double fillBase)
{
// And the initial sample index
var leftmostSampleIndex = triggerPoint - channel.ViewWidthInSamples / 2;
Expand All @@ -454,7 +454,7 @@ private void RenderWave(SKCanvas g, Channel channel, int triggerPoint, SKPaint l
float xScale = (float) channel.Bounds.Width / channel.ViewWidthInSamples;
float yOffset = channel.Bounds.Top + channel.Bounds.Height * 0.5f;
float yScale = -channel.Bounds.Height * 0.5f;
path.Reset();
path.Rewind();
for (var i = 0; i < channel.ViewWidthInSamples; ++i)
{
var sampleValue = channel.GetSample(leftmostSampleIndex + i, false);
Expand All @@ -475,17 +475,22 @@ private void RenderWave(SKCanvas g, Channel channel, int triggerPoint, SKPaint l
}

// Then draw them all in one go...
if (linePaint != null)
// Draw the fill "under" the line
if (fillPaint != null)
{
g.DrawPath(path, linePaint);
// We need to add points to complete the path
// We compute the Y position of this line. -0.5 scales -1..1 to bottom..top.
var baseY = (float)(yOffset + channel.Bounds.Height * -0.5 * fillBase);
fillPath.Rewind();
fillPath.AddPath(path);
fillPath.LineTo(channel.Bounds.Right, baseY);
fillPath.LineTo(channel.Bounds.Left, baseY);
g.DrawPath(fillPath, fillPaint);
}

if (fillPaint != null)
if (linePaint != null)
{
// We need to add points to complete the path
path.LineTo(channel.Bounds.Right, yOffset);
path.LineTo(channel.Bounds.Left, yOffset);
g.DrawPath(path, fillPaint);
g.DrawPath(path, linePaint);
}
}

Expand Down
9 changes: 0 additions & 9 deletions SidWiz/SidWizPlusGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,14 +465,11 @@ private void Render()
// We update this here so the worker thread will get the latest value.
_renderPosition = (float) PreviewTrackbar.Value / PreviewTrackbar.Maximum;

Trace.WriteLine($"Want to render at {_renderPosition}");

// We have two flags to signal the need to render.
// One indicates that we need to render; this can be set while rendering
// to cause it to render again when done.
if (_renderNeeded)
{
Trace.WriteLine("Render is already queued, nothing to do");
return;
}

Expand All @@ -482,15 +479,12 @@ private void Render()
// This ensures we don't start two render tasks at the same time.
if (_renderActive)
{
Trace.WriteLine("Render is already active, not starting task");
return;
}

_renderActive = true;
}

Trace.WriteLine("Starting render task");

// And finally we start the task.
Task.Factory.StartNew(() =>
{
Expand All @@ -500,7 +494,6 @@ private void Render()
float renderPosition;
lock (_renderLock)
{
Trace.WriteLine("Clearing render needed flag");
_renderNeeded = false;
renderPosition = _renderPosition;
}
Expand All @@ -526,11 +519,9 @@ private void Render()
{
if (_renderNeeded)
{
Trace.WriteLine("Render needed flag was set, rendering again");
continue;
}

Trace.WriteLine("Render complete, ending task");
_renderActive = false;
break;
}
Expand Down

0 comments on commit dd915d1

Please sign in to comment.