Support color tags on vertical texts (gradiant works only with horizontal text)
This commit is contained in:
parent
d774c3ac4d
commit
cd316d2ca1
@ -2,7 +2,7 @@ using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using SkiaSharp;
|
||||
|
||||
using static FDK.CSkiaSharpTextRenderer;
|
||||
using Color = System.Drawing.Color;
|
||||
|
||||
namespace FDK {
|
||||
@ -144,6 +144,42 @@ namespace FDK {
|
||||
|
||||
//グラデ(全体)にも対応したいですね?
|
||||
|
||||
List<CSkiaSharpTextRenderer.SStringToken> tokens = new List<CSkiaSharpTextRenderer.SStringToken>();
|
||||
tokens = this.textRenderer.Tokenize(drawstr, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradationBottomColor);
|
||||
|
||||
string purified = this.textRenderer.Purify(drawstr);
|
||||
string[] strList = new string[purified.Length];
|
||||
for (int i = 0; i < purified.Length; i++)
|
||||
strList[i] = purified.Substring(i, 1);
|
||||
SKBitmap[] strImageList = new SKBitmap[purified.Length];
|
||||
|
||||
int nWidth = 0;
|
||||
int nHeight = 0;
|
||||
int _idx = 0;
|
||||
foreach (SStringToken tok in tokens) {
|
||||
string[] splitted = new string[tok.s.Length];
|
||||
for (int i = 0; i < tok.s.Length; i++)
|
||||
splitted[i] = tok.s.Substring(i, 1);
|
||||
|
||||
for (int i = 0; i < splitted.Length; i++) {
|
||||
strImageList[_idx] = this.textRenderer.DrawText(splitted[i], drawmode, tok.TextColor, tok.OutlineColor, secondEdgeColor, tok.GradiantTop, tok.GradiantBottom, edge_Ratio, false);
|
||||
|
||||
//回転する文字
|
||||
if (Rotate_Chara_List_Vertical.Contains(splitted[i])) {
|
||||
using (var surface = new SKCanvas(strImageList[_idx])) {
|
||||
surface.RotateDegrees(90, strImageList[_idx].Width / 2, strImageList[_idx].Height / 2);
|
||||
surface.DrawBitmap(strImageList[_idx], 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
nWidth = Math.Max(nWidth, strImageList[_idx].Width);
|
||||
nHeight += strImageList[_idx].Height - 25;
|
||||
_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
string[] strList = new string[drawstr.Length];
|
||||
for (int i = 0; i < drawstr.Length; i++)
|
||||
strList[i] = drawstr.Substring(i, 1);
|
||||
@ -166,6 +202,7 @@ namespace FDK {
|
||||
nWidth = Math.Max(nWidth, strImageList[i].Width);
|
||||
nHeight += strImageList[i].Height - 25;
|
||||
}
|
||||
*/
|
||||
|
||||
SKImageInfo skImageInfo = new SKImageInfo(nWidth, nHeight);
|
||||
|
||||
|
@ -77,11 +77,11 @@ namespace FDK {
|
||||
|
||||
private const string TagRegex = @"<(/?)([gc](?:\.#[0-9a-fA-F]{6})*?)>";
|
||||
|
||||
private string Purify(string input) {
|
||||
public string Purify(string input) {
|
||||
return Regex.Replace(input, TagRegex, "");
|
||||
}
|
||||
|
||||
private List<SStringToken> Tokenize(string input, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor) {
|
||||
public List<SStringToken> Tokenize(string input, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor) {
|
||||
List<SStringToken> tokens = new List<SStringToken>();
|
||||
Stack<string> tags = new Stack<string>();
|
||||
Stack<SStringToken> tokenStack = new Stack<SStringToken>();
|
||||
|
@ -1,8 +1,13 @@
|
||||
using SkiaSharp;
|
||||
using static FDK.CSkiaSharpTextRenderer;
|
||||
using Color = System.Drawing.Color;
|
||||
|
||||
namespace FDK {
|
||||
internal interface ITextRenderer : IDisposable {
|
||||
SKBitmap DrawText(string drawstr, CFontRenderer.DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter);
|
||||
|
||||
string Purify(string input);
|
||||
|
||||
List<SStringToken> Tokenize(string input, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor);
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,73 @@ namespace System {
|
||||
|
||||
private const string TagRegex = @"<(/?)([gc](?:\.#[0-9a-fA-F]{6})*?)>";
|
||||
|
||||
public static string TrimStringWithTags(this string input, int maxLength) {
|
||||
// This will store the result
|
||||
string result = string.Empty;
|
||||
// This will store the length of characters outside tags
|
||||
int count = 0;
|
||||
|
||||
// Stack to keep track of open tags
|
||||
Stack<string> openTags = new Stack<string>();
|
||||
|
||||
// Use regex to match tags and content
|
||||
var regex = new Regex(TagRegex);
|
||||
var matches = regex.Matches(input);
|
||||
int lastIndex = 0;
|
||||
|
||||
foreach (Match match in matches) {
|
||||
// Add the characters before the current match (which are non-tag characters)
|
||||
if (match.Index > lastIndex) {
|
||||
// Get the substring before the tag
|
||||
string contentBeforeTag = input.Substring(lastIndex, match.Index - lastIndex);
|
||||
|
||||
// Calculate how many characters we can take from this content
|
||||
int charsToTake = Math.Min(maxLength - count, contentBeforeTag.Length);
|
||||
|
||||
// Append the allowed part to the result
|
||||
result += contentBeforeTag.Substring(0, charsToTake);
|
||||
|
||||
// Update the count of characters outside tags
|
||||
count += charsToTake;
|
||||
|
||||
// If we have reached the max length, break
|
||||
if (count >= maxLength) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Process the tag
|
||||
result += match.Value;
|
||||
|
||||
// If it's an opening tag, push it to the stack
|
||||
if (!match.Value.StartsWith("</")) {
|
||||
openTags.Push(match.Value);
|
||||
} else if (openTags.Count > 0) {
|
||||
// If it's a closing tag, pop the corresponding opening tag from the stack
|
||||
openTags.Pop();
|
||||
}
|
||||
|
||||
// Update the last index after the tag
|
||||
lastIndex = match.Index + match.Length;
|
||||
}
|
||||
|
||||
// If there is remaining text after the last tag, handle it
|
||||
if (lastIndex < input.Length && count < maxLength) {
|
||||
string remainingContent = input.Substring(lastIndex);
|
||||
result += remainingContent.Substring(0, Math.Min(maxLength - count, remainingContent.Length));
|
||||
}
|
||||
|
||||
// Close all remaining open tags
|
||||
while (openTags.Count > 0) {
|
||||
string openTag = openTags.Pop();
|
||||
// Convert the opening tag to its closing counterpart
|
||||
string tagName = new Regex(@"<([gc](?:\.#[0-9a-fA-F]{6})*?)>").Match(openTag).Groups[1].Value;
|
||||
result += $"</{tagName[0]}>";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string RemoveTags(this string input) {
|
||||
return Regex.Replace(input, TagRegex, "");
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing;
|
||||
using FDK;
|
||||
using Silk.NET.Maths;
|
||||
using static OpenTaiko.CActSelect曲リスト;
|
||||
using Rectangle = System.Drawing.Rectangle;
|
||||
|
||||
namespace OpenTaiko {
|
||||
@ -336,7 +334,7 @@ namespace OpenTaiko {
|
||||
titleTmp = stNode.ttkタイトル[stNode.ttkタイトル.Length - 1].str;
|
||||
}
|
||||
|
||||
TitleTextureKey ttkTmp = new TitleTextureKey(titleTmp.Substring(0, 2), pfDanPlateTitle, Color.White, Color.Black, 1000);
|
||||
TitleTextureKey ttkTmp = new TitleTextureKey(titleTmp.TrimStringWithTags(2), pfDanPlateTitle, Color.White, Color.Black, 1000);
|
||||
TitleTextureKey.ResolveTitleTextureTate(ttkTmp).t2D中心基準描画(x + OpenTaiko.Skin.DaniSelect_DanPlateTitle_Offset[0], y + OpenTaiko.Skin.DaniSelect_DanPlateTitle_Offset[1]);
|
||||
}
|
||||
}
|
||||
@ -718,7 +716,7 @@ namespace OpenTaiko {
|
||||
}
|
||||
|
||||
// Two char header, will be used for grade unlocking too
|
||||
string tmp = song.ldTitle.GetString("").Substring(0, 2);
|
||||
string tmp = song.ldTitle.GetString("").TrimStringWithTags(2);
|
||||
|
||||
stバー情報[i].ttkタイトル[listSongs[i].DanSongs.Count] = new TitleTextureKey(tmp, pfDanSong, Color.Black, Color.Transparent, 700);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user