Skip to content

Commit

Permalink
Merge pull request #53 from andy840119/fix-font-time-tag-with-wrong-s…
Browse files Browse the repository at this point in the history
…eparator-position

Fix the case that left and right sprite text width are all zero.
  • Loading branch information
andy840119 authored Oct 1, 2021
2 parents 69a48ee + 8cde770 commit 2488e73
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Testing;
using osu.Framework.Timing;
using osuTK.Graphics;

namespace osu.Framework.Font.Tests.Visual.Sprites
{
public class TestSceneKaraokeSpriteText : TestScene
{
private readonly ManualClock manualClock = new();
private readonly KaraokeSpriteText karaokeSpriteText;

public TestSceneKaraokeSpriteText()
Expand Down Expand Up @@ -50,11 +53,25 @@ public TestSceneKaraokeSpriteText()
LeftTextColour = Color4.Green,
RightTextColour = Color4.Red,
};
}

[TestCase(false)]
[TestCase(true)]
public void TestKaraokeSpriteTextTimeTag(bool manualTime)
{
if (manualTime)
{
AddSliderStep("Here can adjust time", 0, 3000, 1000, time =>
{
manualClock.CurrentTime = time;
});
}

AddLabel("Test time tag");
AddStep("Default time tag", () =>
{
var startTime = Time.Current;
var startTime = getStartTime();

karaokeSpriteText.Clock = manualTime ? new FramedClock(manualClock) : Clock;
karaokeSpriteText.TimeTags = new Dictionary<TextIndex, double>
{
{ new TextIndex(0), startTime + 500 },
Expand All @@ -66,7 +83,9 @@ public TestSceneKaraokeSpriteText()
});
AddStep("Time tag with end state", () =>
{
var startTime = Time.Current;
var startTime = getStartTime();

karaokeSpriteText.Clock = manualTime ? new FramedClock(manualClock) : Clock;
karaokeSpriteText.TimeTags = new Dictionary<TextIndex, double>
{
// カ
Expand All @@ -88,7 +107,9 @@ public TestSceneKaraokeSpriteText()
});
AddStep("Time tag with wrong order", () =>
{
var startTime = Time.Current;
var startTime = getStartTime();

karaokeSpriteText.Clock = manualTime ? new FramedClock(manualClock) : Clock;
karaokeSpriteText.TimeTags = new Dictionary<TextIndex, double>
{
{ new TextIndex(4), startTime + 2000 },
Expand All @@ -100,7 +121,9 @@ public TestSceneKaraokeSpriteText()
});
AddStep("Time tag with out of range", () =>
{
var startTime = Time.Current;
var startTime = getStartTime();

karaokeSpriteText.Clock = manualTime ? new FramedClock(manualClock) : Clock;
karaokeSpriteText.TimeTags = new Dictionary<TextIndex, double>
{
{ new TextIndex(-1), startTime + 0 },
Expand All @@ -112,6 +135,26 @@ public TestSceneKaraokeSpriteText()
{ new TextIndex(8), startTime + 2500 },
};
});

AddStep("Only one time-tag", () =>
{
var startTime = getStartTime();

karaokeSpriteText.Clock = manualTime ? new FramedClock(manualClock) : Clock;
karaokeSpriteText.TimeTags = new Dictionary<TextIndex, double>
{
{ new TextIndex(0), startTime + 500 },
};
});

AddStep("None time-tag", () =>
{
karaokeSpriteText.Clock = manualTime ? new FramedClock(manualClock) : Clock;
karaokeSpriteText.TimeTags = null;
});

double getStartTime()
=> manualTime ? 0 : Clock.CurrentTime;
}
}
}
45 changes: 28 additions & 17 deletions osu.Framework.Font/Graphics/Sprites/KaraokeSpriteText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,34 +383,45 @@ protected override bool OnInvalidate(Invalidation invalidation, InvalidationSour
if (!invalidation.HasFlag(Invalidation.Presence) || !hasTimeTag || !hasText)
return result;

// set initial width.
frontLyricTextContainer.Width = 0;
backLyricTextContainer.Width = DrawWidth;

// reset masking transform.
frontLyricTextContainer.ClearTransforms();
backLyricTextContainer.ClearTransforms();

// process time-tag should in the text-range
// filter valid time-tag with order.
var characters = frontLyricText.Characters;
var validTimeTag = TimeTags
.Where(x => x.Key.Index >= 0 && x.Key.Index < Text.Length)
.OrderBy(x => x.Value);
.OrderBy(x => x.Value).ToArray();

// get first time-tag relative start time.
var relativeTime = validTimeTag.FirstOrDefault().Value - Time.Current;

var startTime = validTimeTag.FirstOrDefault().Value;
// should use absolute time to process time-tags.
using (frontLyricTextContainer.BeginAbsoluteSequence(Time.Current))
using (frontLyricTextContainer.BeginAbsoluteSequence(Time.Current))
{
// get transform sequence and set initial delay time.
var frontTransformSequence = frontLyricTextContainer.Delay(relativeTime).Then();
var backTransformSequence = backLyricTextContainer.Delay(relativeTime).Then();

// get transform sequence and set initial delay time.
var frontTransformSequence = frontLyricTextContainer.Delay(startTime - Time.Current).Then();
var backTransformSequence = backLyricTextContainer.Delay(startTime - Time.Current).Then();
foreach (var (textIndex, time) in validTimeTag)
{
// calculate position and duration relative to precious time-tag time.
var characterRectangle = characters[textIndex.Index].DrawRectangle;
var position = textIndex.State == TextIndex.IndexState.Start ? characterRectangle.Left : characterRectangle.Right;
var duration = Math.Max(time - relativeTime, 0);

var previousTime = startTime;
// apply the position with delay time.
frontTransformSequence.ResizeWidthTo(position, duration).Then();
backTransformSequence.ResizeWidthTo(DrawWidth - position, duration).Then();

foreach (var (textIndex, time) in validTimeTag)
{
// text-index should be in the range.
var characterRectangle = characters[textIndex.Index].DrawRectangle;
var position = textIndex.State == TextIndex.IndexState.Start ? characterRectangle.Left : characterRectangle.Right;
var duration = Math.Max(time - previousTime, 0);
frontTransformSequence.ResizeWidthTo(position, duration).Then();
backTransformSequence.ResizeWidthTo(DrawWidth - position, duration).Then();

previousTime = time;
// save current time-tag time for letting next time-tag able to calculate duration.
relativeTime = time;
}
}

return true;
Expand Down

0 comments on commit 2488e73

Please sign in to comment.