protected override void DoLayoutAndRender()
{
if (Renderer.Settings.Staves.Count == 0) return;
var score = Renderer.Score;
var canvas = Renderer.Canvas;
var startIndex = Renderer.Settings.Layout.Get("start", 1);
startIndex--; // map to array index
startIndex = Math.Min(score.MasterBars.Count - 1, Math.Max(0, startIndex));
var currentBarIndex = startIndex;
var endBarIndex = Renderer.Settings.Layout.Get("count", score.MasterBars.Count);
if (endBarIndex < 0) endBarIndex = score.MasterBars.Count;
endBarIndex = startIndex + endBarIndex - 1; // map count to array index
endBarIndex = Math.Min(score.MasterBars.Count - 1, Math.Max(0, endBarIndex));
_group = CreateEmptyStaveGroup();
_group.X = PagePadding[0];
_group.Y = PagePadding[1];
var countPerPartial = Renderer.Settings.Layout.Get("countPerPartial", 10);
var partials = new FastList<HorizontalScreenLayoutPartialInfo>();
var currentPartial = new HorizontalScreenLayoutPartialInfo();
if (Renderer.Settings.Staves.Count > 0)
{
while (currentBarIndex <= endBarIndex)
{
var result = _group.AddBars(Renderer.Tracks, currentBarIndex);
// if we detect that the new renderer is linked to the previous
// renderer, we need to put it into the previous partial
if (currentPartial.MasterBars.Count == 0 && result.IsLinkedToPrevious && partials.Count > 0)
{
var previousPartial = partials[partials.Count - 1];
previousPartial.MasterBars.Add(score.MasterBars[currentBarIndex]);
previousPartial.Width += result.Width;
}
else
{
currentPartial.MasterBars.Add(score.MasterBars[currentBarIndex]);
currentPartial.Width += result.Width;
// no targetPartial here because previous partials already handled this code
if (currentPartial.MasterBars.Count >= countPerPartial)
{
if (partials.Count == 0)
{
currentPartial.Width += _group.X + _group.AccoladeSpacing;
}
partials.Add(currentPartial);
currentPartial = new HorizontalScreenLayoutPartialInfo();
}
}
currentBarIndex++;
}
// don't miss the last partial if not empty
if (currentPartial.MasterBars.Count > 0)
{
if (partials.Count == 0)
{
currentPartial.Width += _group.X + _group.AccoladeSpacing;
}
partials.Add(currentPartial);
}
}
_group.FinalizeGroup(this);
Height = _group.Y + _group.Height + PagePadding[3];
Width = _group.X + _group.Width + PagePadding[2];
// TODO: Find a good way to render the score partwise
// we need to precalculate the final height somehow
//canvas.BeginRender(Width, Height);
//canvas.Color = Renderer.RenderingResources.MainGlyphColor;
//canvas.TextAlign = TextAlign.Left;
//_group.Paint(0, 0, Renderer.Canvas);
//var result = canvas.EndRender();
//OnPartialRenderFinished(new RenderFinishedEventArgs
//{
// TotalWidth = Width,
// TotalHeight = y,
// Width = Width,
// Height = Height,
// RenderResult = result
//});
currentBarIndex = 0;
for (var i = 0; i < partials.Count; i++)
{
var partial = partials[i];
canvas.BeginRender(partial.Width, Height);
canvas.Color = Renderer.RenderingResources.MainGlyphColor;
canvas.TextAlign = TextAlign.Left;
var renderX = _group.GetBarX(partial.MasterBars[0].Index) + _group.AccoladeSpacing;
if (i == 0)
{
renderX -= _group.X + _group.AccoladeSpacing;
}
_group.PaintPartial(-renderX, _group.Y, Renderer.Canvas, currentBarIndex, partial.MasterBars.Count);
var result = canvas.EndRender();
Renderer.OnPartialRenderFinished(new RenderFinishedEventArgs
{
TotalWidth = Width,
TotalHeight = Height,
Width = partial.Width,
Height = Height,
RenderResult = result
});
currentBarIndex += partial.MasterBars.Count;
}
}