diff --git a/osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Formats/NicoKaraDecoderTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Formats/NicoKaraDecoderTest.cs index 5a8b9c705..0aa2d8bb4 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Formats/NicoKaraDecoderTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Formats/NicoKaraDecoderTest.cs @@ -54,7 +54,7 @@ public void TestDecodeNicoKara() var outlineShader = shaders.FirstOrDefault() as OutlineShader; Assert.IsNotNull(outlineShader); Assert.AreEqual(new Color4(255, 255, 255, 255), outlineShader.OutlineColour); - Assert.AreEqual(10, outlineShader.Radius); + Assert.AreEqual(3, outlineShader.Radius); // Test shader convert result. var shadowShader = shaders.LastOrDefault() as ShadowShader; diff --git a/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/KaraokeSkinElementConvertorTest.cs b/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/KaraokeSkinElementConvertorTest.cs index 9906f3b3d..0430e0364 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/KaraokeSkinElementConvertorTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/KaraokeSkinElementConvertorTest.cs @@ -77,7 +77,7 @@ public void TestLyricStyleSerializer() var lyricStyle = LyricStyle.CreateDefault(); const string expected = - "{\"$type\":2,\"left_lyric_text_shaders\":[{\"$type\":\"StepShader\",\"name\":\"Step shader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"OutlineShader\",\"radius\":10,\"outline_colour\":\"#CCA532\"},{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#6B5B2D\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}],\"right_lyric_text_shaders\":[{\"$type\":\"StepShader\",\"name\":\"Step shader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"OutlineShader\",\"radius\":10,\"outline_colour\":\"#5932CC\"},{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#3D2D6B\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}],\"name\":\"Default\"}"; + "{\"$type\":2,\"left_lyric_text_shaders\":[{\"$type\":\"StepShader\",\"name\":\"Step shader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"OutlineShader\",\"radius\":3.0,\"outline_colour\":\"#CCA532\"},{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#6B5B2D\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}],\"right_lyric_text_shaders\":[{\"$type\":\"StepShader\",\"name\":\"Step shader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"OutlineShader\",\"radius\":3.0,\"outline_colour\":\"#5932CC\"},{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#3D2D6B\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}],\"name\":\"Default\"}"; string actual = JsonConvert.SerializeObject(lyricStyle, CreateSettings()); Assert.AreEqual(expected, actual); } @@ -86,7 +86,7 @@ public void TestLyricStyleSerializer() public void TestLyricStyleDeserializer() { const string json = - "{\"$type\":2,\"left_lyric_text_shaders\":[{\"$type\":\"StepShader\",\"name\":\"Step shader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"OutlineShader\",\"radius\":10,\"outline_colour\":\"#CCA532\"},{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#6B5B2D\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}],\"right_lyric_text_shaders\":[{\"$type\":\"StepShader\",\"name\":\"Step shader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"OutlineShader\",\"radius\":10,\"outline_colour\":\"#5932CC\"},{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#3D2D6B\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}],\"name\":\"Default\"}"; + "{\"$type\":2,\"left_lyric_text_shaders\":[{\"$type\":\"StepShader\",\"name\":\"Step shader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"OutlineShader\",\"radius\":3.0,\"outline_colour\":\"#CCA532\"},{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#6B5B2D\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}],\"right_lyric_text_shaders\":[{\"$type\":\"StepShader\",\"name\":\"Step shader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"OutlineShader\",\"radius\":3.0,\"outline_colour\":\"#5932CC\"},{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#3D2D6B\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}],\"name\":\"Default\"}"; var expected = LyricStyle.CreateDefault(); var actual = JsonConvert.DeserializeObject(json, CreateSettings()) as LyricStyle; diff --git a/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/ShaderConvertorTest.cs b/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/ShaderConvertorTest.cs index 9bbdadc24..68f09ade5 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/ShaderConvertorTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/ShaderConvertorTest.cs @@ -25,11 +25,11 @@ public void TestSerializer() { var shader = new ShadowShader { - ShadowOffset = new Vector2(10), + ShadowOffset = new Vector2(3), ShadowColour = new Color4(0.5f, 0.5f, 0.5f, 0.5f), }; - const string expected = "{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#7F7F7F7F\",\"shadow_offset\":{\"x\":10.0,\"y\":10.0}}"; + const string expected = "{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#7F7F7F7F\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}"; string result = JsonConvert.SerializeObject(shader, CreateSettings()); Assert.AreEqual(expected, result); } @@ -37,11 +37,11 @@ public void TestSerializer() [Test] public void TestDeserialize() { - const string json = "{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#7F7F7F7F\",\"shadow_offset\":{\"x\":10.0,\"y\":10.0}}"; + const string json = "{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#7F7F7F7F\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}"; var expected = new ShadowShader { - ShadowOffset = new Vector2(10), + ShadowOffset = new Vector2(3), ShadowColour = new Color4(0.5f, 0.5f, 0.5f, 0.5f), }; var actual = JsonConvert.DeserializeObject(json, CreateSettings()) as ShadowShader; @@ -60,14 +60,14 @@ public void TestSerializerListItems() { new ShadowShader { - ShadowOffset = new Vector2(10), + ShadowOffset = new Vector2(3), ShadowColour = new Color4(0.5f, 0.5f, 0.5f, 0.5f), } } }; const string expected = - "{\"$type\":\"StepShader\",\"name\":\"HelloShader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#7F7F7F7F\",\"shadow_offset\":{\"x\":10.0,\"y\":10.0}}]}"; + "{\"$type\":\"StepShader\",\"name\":\"HelloShader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#7F7F7F7F\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}"; string actual = JsonConvert.SerializeObject(shader, CreateSettings()); Assert.AreEqual(expected, actual); } @@ -76,7 +76,7 @@ public void TestSerializerListItems() public void TestDeserializeListItems() { const string json = - "{\"$type\":\"StepShader\",\"name\":\"HelloShader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#7F7F7F7F\",\"shadow_offset\":{\"x\":10.0,\"y\":10.0}}]}"; + "{\"$type\":\"StepShader\",\"name\":\"HelloShader\",\"draw\":true,\"step_shaders\":[{\"$type\":\"ShadowShader\",\"shadow_colour\":\"#7F7F7F7F\",\"shadow_offset\":{\"x\":3.0,\"y\":3.0}}]}"; var expected = new StepShader { @@ -85,7 +85,7 @@ public void TestDeserializeListItems() { new ShadowShader { - ShadowOffset = new Vector2(10), + ShadowOffset = new Vector2(3), ShadowColour = new Color4(0.5f, 0.5f, 0.5f, 0.5f), } } diff --git a/osu.Game.Rulesets.Karaoke.Tests/Resources/special-skin/default.json b/osu.Game.Rulesets.Karaoke.Tests/Resources/special-skin/default.json index 99d820241..680eec0bf 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Resources/special-skin/default.json +++ b/osu.Game.Rulesets.Karaoke.Tests/Resources/special-skin/default.json @@ -31,7 +31,7 @@ "step_shaders": [ { "$type": "OutlineShader", - "radius": 10, + "radius": 3, "outline_colour": "#CCA532" }, { @@ -53,7 +53,7 @@ "step_shaders": [ { "$type": "OutlineShader", - "radius": 10, + "radius": 3, "outline_colour": "#5932CC" }, { diff --git a/osu.Game.Rulesets.Karaoke.Tests/Resources/special-skin/lyric-styles.json b/osu.Game.Rulesets.Karaoke.Tests/Resources/special-skin/lyric-styles.json index e6f80091d..05dac13a0 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Resources/special-skin/lyric-styles.json +++ b/osu.Game.Rulesets.Karaoke.Tests/Resources/special-skin/lyric-styles.json @@ -11,7 +11,7 @@ "step_shaders": [ { "$type": "OutlineShader", - "radius": 10, + "radius": 3, "outline_colour": "#CCA532" }, { @@ -33,7 +33,7 @@ "step_shaders": [ { "$type": "OutlineShader", - "radius": 10, + "radius": 3, "outline_colour": "#5932CC" }, { diff --git a/osu.Game.Rulesets.Karaoke.Tests/Utils/TextTagUtilsTest.cs b/osu.Game.Rulesets.Karaoke.Tests/Utils/TextTagUtilsTest.cs index 9ca2ff2d5..17e611b4f 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Utils/TextTagUtilsTest.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Utils/TextTagUtilsTest.cs @@ -178,5 +178,18 @@ public void TestGetTextFromLyric(string textTag, string lyric, string expected) string actual = TextTagUtils.GetTextFromLyric(rubyTag, lyric); Assert.AreEqual(expected, actual); } + + [TestCase("[0,1]:ka")] + [TestCase("[1,0]:ka")] // Should be able to convert even if time-tag is invalid. + [TestCase("[-1,1]:ka")] // Should be able to convert even if time-tag is invalid. + public void TestToPositionText(string textTag) + { + var rubyTag = TestCaseTagHelper.ParseRubyTag(textTag); + var actual = TextTagUtils.ToPositionText(rubyTag); + + Assert.AreEqual(rubyTag.Text, actual.Text); + Assert.AreEqual(rubyTag.StartIndex, actual.StartIndex); + Assert.AreEqual(rubyTag.EndIndex, actual.EndIndex); + } } } diff --git a/osu.Game.Rulesets.Karaoke/Beatmaps/Formats/NicoKaraDecoder.cs b/osu.Game.Rulesets.Karaoke/Beatmaps/Formats/NicoKaraDecoder.cs index 62c8653a5..2f92d77ed 100644 --- a/osu.Game.Rulesets.Karaoke/Beatmaps/Formats/NicoKaraDecoder.cs +++ b/osu.Game.Rulesets.Karaoke/Beatmaps/Formats/NicoKaraDecoder.cs @@ -137,7 +137,8 @@ private static OutlineShader createOutlineShader(BrushInfo info, FontInfo fontIn return new OutlineShader { OutlineColour = color, - Radius = (int)radius, + // Notice that should adjust the radius for looking the same. + Radius = (int)(radius / 3), }; static float convertEdgeSize(FontInfo info) => info.EdgeSize; diff --git a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditorSkin.cs b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditorSkin.cs index 0f09cd963..d70a0f363 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditorSkin.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/LyricEditorSkin.cs @@ -51,7 +51,7 @@ public LyricEditorSkin(SkinInfo skin, IStorageResourceProvider resources) { new OutlineShader { - Radius = 4, + Radius = 2, Colour = Color4Extensions.FromHex("#3D2D6B"), OutlineColour = Color4Extensions.FromHex("#CCA532") }, @@ -60,7 +60,7 @@ public LyricEditorSkin(SkinInfo skin, IStorageResourceProvider resources) { new OutlineShader { - Radius = 4, + Radius = 2, OutlineColour = Color4Extensions.FromHex("#5932CC") }, } diff --git a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/Rows/Components/EditorLyricPiece.cs b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/Rows/Components/EditorLyricPiece.cs index 4a295ebae..d36b434be 100644 --- a/osu.Game.Rulesets.Karaoke/Edit/Lyrics/Rows/Components/EditorLyricPiece.cs +++ b/osu.Game.Rulesets.Karaoke/Edit/Lyrics/Rows/Components/EditorLyricPiece.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Sprites; -using osu.Game.Rulesets.Karaoke.Extensions; using osu.Game.Rulesets.Karaoke.Graphics.Sprites; using osu.Game.Rulesets.Karaoke.Objects; using osu.Game.Rulesets.Karaoke.Objects.Types; @@ -165,50 +164,16 @@ static FontUsage getFont(float? charSize = null) public class EditorLyricSpriteText : LyricSpriteText { public RectangleF GetRubyTagPosition(RubyTag rubyTag) - { - var matchedRuby = Rubies.FirstOrDefault(x => propertyMatched(x, rubyTag)); - int rubyIndex = Rubies.IndexOf(matchedRuby); - if (rubyIndex < 0) - throw new ArgumentOutOfRangeException(nameof(rubyIndex)); - - int startCharacterIndex = Text.Length + skinIndex(Rubies, rubyIndex); - int count = matchedRuby.Text.Length; - var rectangles = Characters.ToList().GetRange(startCharacterIndex, count).Select(x => x.DrawRectangle).ToArray(); - return RectangleFUtils.Union(rectangles); - } + => GetRubyTagPosition(TextTagUtils.ToPositionText(rubyTag)); public RectangleF GetRomajiTagPosition(RomajiTag romajiTag) - { - var matchedRomaji = Romajies.FirstOrDefault(x => propertyMatched(x, romajiTag)); - int romajiIndex = Romajies.IndexOf(matchedRomaji); - if (romajiIndex < 0) - throw new ArgumentOutOfRangeException(nameof(romajiIndex)); - - int startCharacterIndex = Text.Length + skinIndex(Rubies, Rubies.Count) + skinIndex(Romajies, romajiIndex); - int count = matchedRomaji.Text.Length; - var rectangles = Characters.ToList().GetRange(startCharacterIndex, count).Select(x => x.DrawRectangle).ToArray(); - return RectangleFUtils.Union(rectangles); - } + => GetRomajiTagPosition(TextTagUtils.ToPositionText(romajiTag)); public Vector2 GetTimeTagPosition(TextIndex index) { - if (string.IsNullOrEmpty(Text)) - return default; - - int charIndex = Math.Min(index.Index, Text.Length - 1); - var character = Characters[charIndex]; - var drawRectangle = character.DrawRectangle; - - float x = index.State == TextIndex.IndexState.Start ? drawRectangle.Left : drawRectangle.Right; - float y = drawRectangle.Top - character.YOffset + LineBaseHeight; - return new Vector2(x, y); + var drawRectangle = GetCharacterRectangle(index.Index); + return index.State == TextIndex.IndexState.Start ? drawRectangle.BottomLeft : drawRectangle.BottomRight; } - - private int skinIndex(IEnumerable positionTexts, int endIndex) - => positionTexts.Where((_, i) => i < endIndex).Sum(x => x.Text.Length); - - private bool propertyMatched(PositionText positionText, ITextTag textTag) - => positionText.StartIndex == textTag.StartIndex && positionText.EndIndex == textTag.EndIndex && positionText.Text == textTag.Text; } } } diff --git a/osu.Game.Rulesets.Karaoke/Graphics/Sprites/DrawableKaraokeSpriteText.cs b/osu.Game.Rulesets.Karaoke/Graphics/Sprites/DrawableKaraokeSpriteText.cs index cf1878bb1..44ff72da2 100644 --- a/osu.Game.Rulesets.Karaoke/Graphics/Sprites/DrawableKaraokeSpriteText.cs +++ b/osu.Game.Rulesets.Karaoke/Graphics/Sprites/DrawableKaraokeSpriteText.cs @@ -73,7 +73,7 @@ private void updateRubies() { if (chunkIndex == whole_chunk_index) { - Rubies = DisplayRuby ? rubyTagsBindable?.Select(x => new PositionText(x.Text, x.StartIndex, x.EndIndex)).ToArray() : null; + Rubies = DisplayRuby ? rubyTagsBindable?.Select(TextTagUtils.ToPositionText).ToArray() : null; } else { @@ -85,7 +85,7 @@ private void updateRomajies() { if (chunkIndex == whole_chunk_index) { - Romajies = DisplayRomaji ? romajiTagsBindable?.Select(x => new PositionText(x.Text, x.StartIndex, x.EndIndex)).ToArray() : null; + Romajies = DisplayRomaji ? romajiTagsBindable?.Select(TextTagUtils.ToPositionText).ToArray() : null; } else { diff --git a/osu.Game.Rulesets.Karaoke/Graphics/Sprites/DrawableLyricSpriteText.cs b/osu.Game.Rulesets.Karaoke/Graphics/Sprites/DrawableLyricSpriteText.cs index 817a5c964..c4d1518b6 100644 --- a/osu.Game.Rulesets.Karaoke/Graphics/Sprites/DrawableLyricSpriteText.cs +++ b/osu.Game.Rulesets.Karaoke/Graphics/Sprites/DrawableLyricSpriteText.cs @@ -5,6 +5,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets.Karaoke.Objects; +using osu.Game.Rulesets.Karaoke.Utils; namespace osu.Game.Rulesets.Karaoke.Graphics.Sprites { @@ -33,12 +34,12 @@ public DrawableLyricSpriteText(Lyric lyric) private void updateRubies() { - Rubies = rubyTagsBindable.Select(x => new PositionText(x.Text, x.StartIndex, x.EndIndex)).ToArray(); + Rubies = rubyTagsBindable.Select(TextTagUtils.ToPositionText).ToArray(); } private void updateRomajies() { - Romajies = romajiTagsBindable.Select(x => new PositionText(x.Text, x.StartIndex, x.EndIndex)).ToArray(); + Romajies = romajiTagsBindable.Select(TextTagUtils.ToPositionText).ToArray(); } } } diff --git a/osu.Game.Rulesets.Karaoke/Resources/Skin/Default/default.json b/osu.Game.Rulesets.Karaoke/Resources/Skin/Default/default.json index 99d820241..680eec0bf 100644 --- a/osu.Game.Rulesets.Karaoke/Resources/Skin/Default/default.json +++ b/osu.Game.Rulesets.Karaoke/Resources/Skin/Default/default.json @@ -31,7 +31,7 @@ "step_shaders": [ { "$type": "OutlineShader", - "radius": 10, + "radius": 3, "outline_colour": "#CCA532" }, { @@ -53,7 +53,7 @@ "step_shaders": [ { "$type": "OutlineShader", - "radius": 10, + "radius": 3, "outline_colour": "#5932CC" }, { diff --git a/osu.Game.Rulesets.Karaoke/Skinning/Elements/LyricStyle.cs b/osu.Game.Rulesets.Karaoke/Skinning/Elements/LyricStyle.cs index 70ee7f9cc..11135d67f 100644 --- a/osu.Game.Rulesets.Karaoke/Skinning/Elements/LyricStyle.cs +++ b/osu.Game.Rulesets.Karaoke/Skinning/Elements/LyricStyle.cs @@ -27,7 +27,7 @@ public class LyricStyle : IKaraokeSkinElement { new OutlineShader { - Radius = 10, + Radius = 3, OutlineColour = Color4Extensions.FromHex("#CCA532") }, new ShadowShader @@ -47,7 +47,7 @@ public class LyricStyle : IKaraokeSkinElement { new OutlineShader { - Radius = 10, + Radius = 3, OutlineColour = Color4Extensions.FromHex("#5932CC") }, new ShadowShader diff --git a/osu.Game.Rulesets.Karaoke/Utils/TextTagUtils.cs b/osu.Game.Rulesets.Karaoke/Utils/TextTagUtils.cs index b96e036cc..2bf8a6fba 100644 --- a/osu.Game.Rulesets.Karaoke/Utils/TextTagUtils.cs +++ b/osu.Game.Rulesets.Karaoke/Utils/TextTagUtils.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets.Karaoke.Objects.Types; namespace osu.Game.Rulesets.Karaoke.Utils @@ -80,5 +81,8 @@ public static string GetTextFromLyric(T textTag, string lyric) where T : ITex (int startIndex, int endIndex) = GetFixedIndex(textTag, lyric); return lyric.Substring(startIndex, endIndex - startIndex); } + + public static PositionText ToPositionText(T textTag) where T : ITextTag + => new(textTag.Text, textTag.StartIndex, textTag.EndIndex); } } diff --git a/osu.Game.Rulesets.Karaoke/osu.Game.Rulesets.Karaoke.csproj b/osu.Game.Rulesets.Karaoke/osu.Game.Rulesets.Karaoke.csproj index 92f1b92de..a5aa04679 100644 --- a/osu.Game.Rulesets.Karaoke/osu.Game.Rulesets.Karaoke.csproj +++ b/osu.Game.Rulesets.Karaoke/osu.Game.Rulesets.Karaoke.csproj @@ -10,7 +10,7 @@ - +