1
0
mirror of synced 2024-11-27 17:00:50 +01:00

Support color tags on vertical texts (gradiant works only with horizontal text)

This commit is contained in:
0auBSQ 2024-10-02 00:56:12 +09:00
parent d774c3ac4d
commit cd316d2ca1
5 changed files with 115 additions and 8 deletions

View File

@ -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);

View File

@ -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>();

View File

@ -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);
}
}

View File

@ -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, "");
}

View File

@ -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);