Created
March 26, 2022 13:09
-
-
Save Masterexa/013577b66a94ae00dbe6b678e8760e66 to your computer and use it in GitHub Desktop.
TextMeshProのルビ振りコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Text; | |
using TMPro; | |
using UnityEngine; | |
namespace Kimiguna.Unity | |
{ | |
public class RubyExample : MonoBehaviour | |
{ | |
[SerializeField] TMP_Text m_text; | |
// Use this for initialization | |
void Start() | |
{ | |
var builder = new StringBuilder(); | |
float widthMul = 1.0f; | |
// グループルビ | |
builder.Append("<indent=0>グループルビ:<indent=20%>"); | |
builder.AppendRubyLine("叛逆", "リベリオン"); | |
builder.AppendRubyLine("百舌鳥", "もず"); | |
builder.AppendRubyLine("田町", "たまち"); | |
builder.AppendRubyLine("花鳥風月", "かちょうふうげつ"); | |
builder.Append("\n"); | |
// モノルビ | |
builder.Append("<indent=0>モノルビ:<indent=20%>"); | |
builder.AppendRuby("田", "た", widthMultiply:widthMul); | |
builder.AppendRubyLine("町", "まち", widthMultiply: widthMul); | |
builder.AppendRuby("花", "か", widthMultiply: widthMul); | |
builder.AppendRuby("鳥", "ちょう", widthMultiply: widthMul); | |
builder.AppendRuby("風", "ふう", widthMultiply: widthMul); | |
builder.AppendRubyLine("月", "げつ", widthMultiply: widthMul); | |
builder.Append("\n"); | |
// 例文 | |
builder.Append("<indent=0>例文:<indent=1em>\n"); | |
builder.Append("そのころわたくしは、モリーオ市の博物局に勤めて"); | |
builder.AppendRuby("居", "お"); | |
builder.Append("りました。\n十八等官でしたから役所のなかでも、ずうっと下の方でしたし"); | |
builder.AppendRuby("俸給", "ほうきゅう"); | |
builder.Append("もほんのわずかでしたが、受持ちが標本の採集や整理で生れ付き好きなことでしたから、わたくしは毎日ずいぶん愉快にはたらきました。"); | |
m_text.text = builder.ToString(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Text; | |
using UnityEngine; | |
namespace Kimiguna.Unity | |
{ | |
public static class TextMeshProRuby | |
{ | |
/// <summary> | |
/// ルビを生成 | |
/// </summary> | |
/// <param name="baseText">ベーステキスト</param> | |
/// <param name="rubyText">ルビテキスト</param> | |
/// <param name="voffset">ルビの垂直オフセット</param> | |
/// <param name="removeRubyHeight">ルビの行の高さを0に指定するか?</param> | |
/// <param name="baseLineHeight">元の行の高さ(<paramref name="removeRubyHeight"/>がtrueのときのみ使用)</param> | |
/// <param name="widthMultiply">テキスト幅倍数</param> | |
/// <param name="rubyFontScale">ルビのフォントサイズ(倍数)</param> | |
public static void AppendRuby(this StringBuilder builder, string baseText, string rubyText, float voffset = 1f, bool removeRubyHeight = false, string baseLineHeight = "100%", float widthMultiply = 1f, float rubyFontScale = 0.5f) | |
{ | |
Generate(builder, baseText, rubyText, voffset, removeRubyHeight, baseLineHeight, widthMultiply, rubyFontScale); | |
} | |
/// <summary> | |
/// ルビを生成 | |
/// </summary> | |
/// <param name="baseText">ベーステキスト</param> | |
/// <param name="rubyText">ルビテキスト</param> | |
/// <param name="voffset">ルビの垂直オフセット</param> | |
/// <param name="removeRubyHeight">ルビの行の高さを0に指定するか?</param> | |
/// <param name="baseLineHeight">元の行の高さ(<paramref name="removeRubyHeight"/>がtrueのときのみ使用)</param> | |
/// <param name="widthMultiply">テキスト幅倍数</param> | |
/// <param name="rubyFontScale">ルビのフォントサイズ(倍数)</param> | |
public static void AppendRubyLine(this StringBuilder builder, string baseText, string rubyText, float voffset = 1f, bool removeRubyHeight = false, string baseLineHeight = "100%", float widthMultiply = 1f, float rubyFontScale = 0.5f) | |
{ | |
builder.AppendRuby(baseText, rubyText, voffset, removeRubyHeight, baseLineHeight, widthMultiply, rubyFontScale); | |
builder.AppendLine(); | |
} | |
/// <summary> | |
/// ルビを生成 | |
/// </summary> | |
/// <param name="baseText">ベーステキスト</param> | |
/// <param name="rubyText">ルビテキスト</param> | |
/// <param name="voffset">ルビの垂直オフセット</param> | |
/// <param name="removeRubyHeight">ルビの行の高さを0に指定するか?</param> | |
/// <param name="baseLineHeight">元の行の高さ(<paramref name="removeRubyHeight"/>がtrueのときのみ使用)</param> | |
/// <param name="widthMultiply">テキスト幅倍数</param> | |
/// <param name="rubyFontScale">ルビのフォントサイズ(倍数)</param> | |
/// <returns></returns> | |
public static string Generate(string baseText, string rubyText, float voffset = 1f, bool removeRubyHeight = false, string baseLineHeight = "100%", float widthMultiply=1f, float rubyFontScale = 0.5f) | |
{ | |
var builder = new StringBuilder(); | |
Generate(builder, baseText, rubyText, voffset, removeRubyHeight, baseLineHeight, rubyFontScale); | |
return builder.ToString(); | |
} | |
/// <summary> | |
/// ルビを生成 | |
/// </summary> | |
/// <param name="builder">出力用<see cref="StringBuilder"/></param> | |
/// <param name="baseText">ベーステキスト</param> | |
/// <param name="rubyText">ルビテキスト</param> | |
/// <param name="voffset">ルビの垂直オフセット</param> | |
/// <param name="removeRubyHeight">ルビの行の高さを0に指定するか?</param> | |
/// <param name="baseLineHeight">元の行の高さ(<paramref name="removeRubyHeight"/>がtrueのときのみ使用)</param> | |
/// <param name="widthMultiply">テキスト幅倍数</param> | |
/// <param name="rubyFontScale">ルビのフォントサイズ(倍数)</param> | |
public static void Generate(StringBuilder builder, string baseText, string rubyText, float voffset = 1f, bool removeRubyHeight = false, string baseLineHeight="100%", float widthMultiply = 1f, float rubyFontScale = 0.5f) | |
{ | |
// ルビが空のとき以外に処理 | |
if (!string.IsNullOrWhiteSpace(rubyText)) | |
{ | |
// 事前計算 | |
float baseLength = baseText.Length; | |
float rubyLength = rubyText.Length; | |
bool displayBase = baseText.Length > 0; | |
// テキストの幅を計算(em単位) | |
// | |
// ベースとルビに必要な幅のうち、値が大きいものを設定 | |
float baseMinWidth = baseLength*widthMultiply; | |
float rubyMinWidth = rubyLength * rubyFontScale; | |
float width = Mathf.Max(baseMinWidth, rubyMinWidth); | |
// 等幅を計算 | |
float baseMs = width / baseLength; | |
float rubyMs = width / rubyLength * (1 / rubyFontScale); | |
// ↓↓↓文字列生成 | |
// 改行防止 | |
builder.Append("<nobr>"); | |
// ベースの出力と垂直オフセット | |
if (displayBase) | |
{ | |
// ベース | |
builder.Append($"<mspace={baseMs:F2}em>"); | |
builder.Append(baseText); | |
builder.Append($"<space={-width:F2}em></mspace>"); | |
// 垂直オフセット | |
builder.Append($"<voffset={voffset:F2}em>"); | |
// ルビの行の高さを0に設定 | |
if( removeRubyHeight ) | |
{ | |
builder.Append("<line-height=0%>"); | |
} | |
} | |
// ルビの出力 | |
builder.Append($"<size={rubyFontScale * 100f:F0}%><mspace={rubyMs:F2}em>"); | |
builder.Append(rubyText); | |
builder.Append("</mspace></size>"); | |
if (displayBase) | |
{ | |
// 行の高さを元に戻す | |
if( removeRubyHeight ) | |
{ | |
builder.Append($"<line-height={baseLineHeight}>"); | |
} | |
// 垂直オフセット | |
builder.Append("</voffset>"); | |
} | |
builder.Append("<nobr>"); | |
} | |
else{ | |
builder.Append(baseText); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment