2019-11-22 08:46:25 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Globalization;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using Nikse.SubtitleEdit.Core.SubtitleFormats;
|
|
|
|
|
|
|
|
|
|
namespace Nikse.SubtitleEdit.Core
|
|
|
|
|
{
|
|
|
|
|
public static class NetflixImsc11JapaneseToAss
|
|
|
|
|
{
|
|
|
|
|
private static string BoutenTagToUnicode(string tag)
|
|
|
|
|
{
|
|
|
|
|
switch (tag)
|
|
|
|
|
{
|
|
|
|
|
case "bouten-dot-before":
|
|
|
|
|
case "bouten-dot-after":
|
|
|
|
|
case "bouten-dot-outside":
|
|
|
|
|
return "•";
|
|
|
|
|
case "bouten-filled-circle-outside":
|
|
|
|
|
return "●";
|
|
|
|
|
case "bouten-open-circle-outside":
|
|
|
|
|
return "○";
|
|
|
|
|
case "bouten-open-dot-outside":
|
|
|
|
|
return "◦";
|
|
|
|
|
case "bouten-filled-sesame-outside":
|
|
|
|
|
return "﹅";
|
|
|
|
|
case "bouten-open-sesame-outside":
|
|
|
|
|
return "﹆";
|
|
|
|
|
case "bouten-auto-outside":
|
|
|
|
|
case "bouten-auto":
|
|
|
|
|
return "﹅";
|
|
|
|
|
default:
|
|
|
|
|
return " ";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static List<Paragraph> SplitToAssRenderLines(Paragraph p, int width, int height)
|
|
|
|
|
{
|
|
|
|
|
if (p.Text.StartsWith("{\\an7}", StringComparison.Ordinal) || p.Text.StartsWith("{\\an9}", StringComparison.Ordinal)) // vertical text
|
|
|
|
|
{
|
|
|
|
|
return MakeVerticalParagraphs(p, width);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:48:23 +01:00
|
|
|
|
return MakeHorizontalParagraphs(p, width, height);
|
2019-11-22 08:46:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static List<Paragraph> MakeHorizontalParagraphs(Paragraph p, int width, int height)
|
|
|
|
|
{
|
|
|
|
|
var lines = p.Text.SplitToLines();
|
2019-11-22 13:19:35 +01:00
|
|
|
|
var adjustment = 34;
|
2019-11-22 20:37:13 +01:00
|
|
|
|
var startY = height - lines.Count * 2 * adjustment + 30;
|
2019-11-22 19:48:23 +01:00
|
|
|
|
if (p.Text.StartsWith("{\\an8", StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
startY = 40;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 08:46:25 +01:00
|
|
|
|
var list = new List<Paragraph>();
|
|
|
|
|
var furiganaList = new List<Paragraph>();
|
2019-11-22 19:48:23 +01:00
|
|
|
|
var rubyOn = false;
|
2019-11-23 20:37:02 +01:00
|
|
|
|
var italinOn = false;
|
2019-11-22 19:48:23 +01:00
|
|
|
|
int startX;
|
|
|
|
|
using (var g = Graphics.FromHwnd(IntPtr.Zero))
|
|
|
|
|
{
|
2019-11-24 13:51:37 +01:00
|
|
|
|
var actualText = NetflixImsc11Japanese.RemoveTags(HtmlUtil.RemoveHtmlTags(p.Text, true));
|
2019-11-22 19:48:23 +01:00
|
|
|
|
var actualTextSize = g.MeasureString(actualText, new Font(SystemFonts.DefaultFont.FontFamily, 20));
|
|
|
|
|
startX = (int)(width / 2.0 - actualTextSize.Width / 2.0);
|
|
|
|
|
if (p.Text.StartsWith("{\\an5", StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
startY = (int)(height / 2.0 - actualTextSize.Height / 2.0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 08:46:25 +01:00
|
|
|
|
for (var index = 0; index < lines.Count; index++)
|
|
|
|
|
{
|
|
|
|
|
var line = lines[index];
|
2019-11-23 20:37:02 +01:00
|
|
|
|
if (italinOn)
|
|
|
|
|
{
|
|
|
|
|
line = "<i>" + line;
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
var actual = new StringBuilder();
|
|
|
|
|
int i = 0;
|
|
|
|
|
while (i < line.Length)
|
|
|
|
|
{
|
|
|
|
|
if (line.Substring(i).StartsWith("{\\"))
|
|
|
|
|
{
|
|
|
|
|
var end = line.IndexOf('}', i);
|
|
|
|
|
if (end < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = end + 1;
|
|
|
|
|
}
|
|
|
|
|
else if (line.Substring(i).StartsWith("<i>", StringComparison.Ordinal) || line.Substring(i).StartsWith("<u>", StringComparison.Ordinal) || line.Substring(i).StartsWith("<b>", StringComparison.Ordinal))
|
|
|
|
|
{
|
2019-11-23 06:31:18 +01:00
|
|
|
|
actual.Append("{\\i1}");
|
2019-11-22 08:46:25 +01:00
|
|
|
|
i += 3;
|
2019-11-23 20:37:02 +01:00
|
|
|
|
italinOn = true;
|
2019-11-22 08:46:25 +01:00
|
|
|
|
}
|
|
|
|
|
else if (line.Substring(i).StartsWith("</i>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</u>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</b>", StringComparison.Ordinal))
|
|
|
|
|
{
|
2019-11-23 06:31:18 +01:00
|
|
|
|
actual.Append("{\\i0}");
|
2019-11-22 08:46:25 +01:00
|
|
|
|
i += 4;
|
2019-11-23 20:37:02 +01:00
|
|
|
|
italinOn = false;
|
2019-11-22 08:46:25 +01:00
|
|
|
|
}
|
|
|
|
|
else if (line.Substring(i).StartsWith("<bouten-", StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
var end = line.IndexOf('>', i);
|
|
|
|
|
if (end < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (end + 1 >= line.Length)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var endTagStart = line.IndexOf("</", end, StringComparison.Ordinal);
|
|
|
|
|
if (endTagStart < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var tag = line.Substring(i + 1, end - i - 1);
|
|
|
|
|
var text = line.Substring(end + 1, endTagStart - end - 1);
|
2019-11-22 19:48:23 +01:00
|
|
|
|
|
2019-11-22 08:46:25 +01:00
|
|
|
|
foreach (var ch in text)
|
|
|
|
|
{
|
|
|
|
|
var furiganaChar = BoutenTagToUnicode(tag);
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(furiganaChar))
|
|
|
|
|
{
|
|
|
|
|
furiganaList.Add(new Paragraph($"{{\\alpha&FF&}}{actual}{{\\alpha&0&}}{furiganaChar}", p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
|
|
|
|
actual.Append(ch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var endTagEnd = line.IndexOf('>', endTagStart);
|
|
|
|
|
if (endTagEnd < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = endTagEnd + 1;
|
|
|
|
|
}
|
2019-11-22 19:48:23 +01:00
|
|
|
|
else if (line.Substring(i).StartsWith("<ruby-container>", StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
var baseTextStart = line.IndexOf("<ruby-base>", i, StringComparison.Ordinal);
|
|
|
|
|
var baseTextEnd = line.IndexOf("</ruby-base>", i, StringComparison.Ordinal);
|
|
|
|
|
if (baseTextStart < 0 || baseTextEnd < 0)
|
|
|
|
|
{
|
|
|
|
|
baseTextStart = line.IndexOf("<ruby-base-italic>", i, StringComparison.Ordinal);
|
|
|
|
|
baseTextEnd = line.IndexOf("</ruby-base-italic>", i, StringComparison.Ordinal);
|
|
|
|
|
if (baseTextStart < 0 || baseTextEnd < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
baseTextStart += "<ruby-base>".Length;
|
|
|
|
|
var baseText = line.Substring(baseTextStart, baseTextEnd - baseTextStart);
|
|
|
|
|
|
|
|
|
|
var extraText = string.Empty;
|
|
|
|
|
var extraTextStart = line.IndexOf("<ruby-text>", i, StringComparison.Ordinal);
|
|
|
|
|
var extraTextEnd = line.IndexOf("</ruby-text>", i, StringComparison.Ordinal);
|
|
|
|
|
if (extraTextStart >= 0 || extraTextEnd >= 0 && extraTextStart < extraTextEnd)
|
|
|
|
|
{
|
|
|
|
|
extraTextStart += "<ruby-text>".Length;
|
|
|
|
|
extraText = line.Substring(extraTextStart, extraTextEnd - extraTextStart);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 20:37:13 +01:00
|
|
|
|
if (string.IsNullOrEmpty(extraText))
|
|
|
|
|
{
|
|
|
|
|
extraTextStart = line.IndexOf("<ruby-text-italic>", i, StringComparison.Ordinal);
|
|
|
|
|
extraTextEnd = line.IndexOf("</ruby-text-italic>", i, StringComparison.Ordinal);
|
|
|
|
|
if (extraTextStart >= 0 || extraTextEnd >= 0 && extraTextStart < extraTextEnd)
|
|
|
|
|
{
|
|
|
|
|
extraTextStart += "<ruby-text-italic>".Length;
|
|
|
|
|
extraText = line.Substring(extraTextStart, extraTextEnd - extraTextStart);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:48:23 +01:00
|
|
|
|
var extraTextAfter = string.Empty;
|
|
|
|
|
var extraTextStartAfter = line.IndexOf("<ruby-text-after>", i, StringComparison.Ordinal);
|
|
|
|
|
var extraTextEndAfter = line.IndexOf("</ruby-text-after>", i, StringComparison.Ordinal);
|
|
|
|
|
if (extraTextStartAfter >= 0 || extraTextEndAfter >= 0 && extraTextStartAfter < extraTextEndAfter)
|
|
|
|
|
{
|
|
|
|
|
extraTextStartAfter += "<ruby-text-after>".Length;
|
|
|
|
|
extraText = line.Substring(extraTextStartAfter, extraTextEndAfter - extraTextStartAfter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var preFurigana = string.Empty;
|
|
|
|
|
if (actual.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
preFurigana = $"{{\\alpha&FF&}}{actual.ToString().TrimEnd()}{{\\alpha&0&}}";
|
|
|
|
|
}
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(extraText))
|
|
|
|
|
{
|
|
|
|
|
furiganaList.Add(new Paragraph($"{preFurigana}{{\\fs20}}{extraText}", p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(extraTextAfter))
|
|
|
|
|
{
|
|
|
|
|
furiganaList.Add(new Paragraph($"{preFurigana}{{\\fs20}} {extraTextAfter}", p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
|
|
|
|
actual.Append(baseText);
|
|
|
|
|
|
|
|
|
|
var endTagEnd = line.IndexOf("</ruby-container>", i, StringComparison.Ordinal);
|
|
|
|
|
if (endTagEnd < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
i = endTagEnd + "</ruby-container>".Length;
|
|
|
|
|
rubyOn = true;
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
actual.Append(line.Substring(i, 1));
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var actualText = actual.ToString().TrimEnd();
|
|
|
|
|
bool displayBefore = lines.Count == 2 && index == 0 || lines.Count == 1;
|
|
|
|
|
if (displayBefore && furiganaList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
foreach (var fp in furiganaList)
|
|
|
|
|
{
|
|
|
|
|
var beforeText = "{\\an1}{\\pos(" + startX + "," + startY + ")}" + fp.Text;
|
|
|
|
|
list.Add(new Paragraph(beforeText, p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
|
|
|
|
startY += adjustment;
|
2019-11-22 19:48:23 +01:00
|
|
|
|
if (rubyOn && index == 0 && lines.Count == 2)
|
|
|
|
|
{
|
|
|
|
|
startY += 3;
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
actualText = "{\\an1}{\\pos(" + startX + "," + startY + ")}" + actualText;
|
|
|
|
|
|
|
|
|
|
list.Add(new Paragraph(actualText, p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
startY += adjustment;
|
|
|
|
|
|
|
|
|
|
if (!displayBefore && furiganaList.Count > 0)
|
|
|
|
|
{
|
2019-11-22 19:48:23 +01:00
|
|
|
|
if (rubyOn && index == 1 && lines.Count == 2)
|
|
|
|
|
{
|
|
|
|
|
startY = (int)(startY - adjustment * 0.4);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 08:46:25 +01:00
|
|
|
|
foreach (var fp in furiganaList)
|
|
|
|
|
{
|
|
|
|
|
var beforeText = "{\\an1}{\\pos(" + startX + "," + startY + ")}" + fp.Text;
|
|
|
|
|
list.Add(new Paragraph(beforeText, p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
|
|
|
|
startY += adjustment;
|
|
|
|
|
}
|
|
|
|
|
furiganaList.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static List<Paragraph> MakeVerticalParagraphs(Paragraph p, int width)
|
|
|
|
|
{
|
|
|
|
|
var lines = p.Text.SplitToLines();
|
2019-11-22 13:19:35 +01:00
|
|
|
|
var adjustment = 34;
|
2019-11-22 08:46:25 +01:00
|
|
|
|
var startX = 9 + lines.Count * 2 * adjustment;
|
|
|
|
|
var leftAlign = p.Text.StartsWith("{\\an7}", StringComparison.Ordinal);
|
|
|
|
|
if (!leftAlign)
|
|
|
|
|
{
|
|
|
|
|
startX = width - 50;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string pre = p.Text.Substring(0, 5);
|
|
|
|
|
var list = new List<Paragraph>();
|
2019-11-22 19:48:23 +01:00
|
|
|
|
var furiganaList = new List<Paragraph>();
|
|
|
|
|
var rubyOn = false;
|
2019-11-23 20:37:02 +01:00
|
|
|
|
var italinOn = false;
|
2019-11-22 08:46:25 +01:00
|
|
|
|
for (var index = 0; index < lines.Count; index++)
|
|
|
|
|
{
|
|
|
|
|
var line = lines[index];
|
|
|
|
|
var actual = new StringBuilder();
|
|
|
|
|
int i = 0;
|
2019-11-23 20:37:02 +01:00
|
|
|
|
if (italinOn)
|
|
|
|
|
{
|
|
|
|
|
line = "<i>" + line;
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
while (i < line.Length)
|
|
|
|
|
{
|
|
|
|
|
if (line.Substring(i).StartsWith("{\\"))
|
|
|
|
|
{
|
|
|
|
|
var end = line.IndexOf('}', i);
|
|
|
|
|
if (end < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = end + 1;
|
|
|
|
|
}
|
|
|
|
|
else if (line.Substring(i).StartsWith("<i>", StringComparison.Ordinal) || line.Substring(i).StartsWith("<u>", StringComparison.Ordinal) || line.Substring(i).StartsWith("<b>", StringComparison.Ordinal))
|
|
|
|
|
{
|
2019-11-23 06:31:18 +01:00
|
|
|
|
actual.Append("{\\i1}");
|
2019-11-22 08:46:25 +01:00
|
|
|
|
i += 3;
|
2019-11-23 20:37:02 +01:00
|
|
|
|
italinOn = true;
|
2019-11-22 08:46:25 +01:00
|
|
|
|
}
|
|
|
|
|
else if (line.Substring(i).StartsWith("</i>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</u>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</b>", StringComparison.Ordinal))
|
|
|
|
|
{
|
2019-11-23 06:31:18 +01:00
|
|
|
|
actual.Append("{\\i0}");
|
2019-11-22 08:46:25 +01:00
|
|
|
|
i += 4;
|
2019-11-23 20:37:02 +01:00
|
|
|
|
italinOn = false;
|
2019-11-22 08:46:25 +01:00
|
|
|
|
}
|
2019-11-22 13:19:35 +01:00
|
|
|
|
else if (line.Substring(i).StartsWith("<horizontalDigit>", StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
var end = line.IndexOf('>', i);
|
|
|
|
|
if (end < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var endTagStart = line.IndexOf("</", end, StringComparison.Ordinal);
|
|
|
|
|
if (endTagStart < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var text = line.Substring(end + 1, endTagStart - end - 1);
|
|
|
|
|
actual.Append(text);
|
|
|
|
|
actual.AppendLine();
|
|
|
|
|
i = endTagStart + "</horizontalDigit>".Length;
|
|
|
|
|
}
|
|
|
|
|
else if (line.Substring(i).StartsWith("</horizontalDigit>", StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
i += "</horizontalDigit>".Length;
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
else if (line.Substring(i).StartsWith("<bouten-", StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
var end = line.IndexOf('>', i);
|
|
|
|
|
if (end < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (end + 1 >= line.Length)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var endTagStart = line.IndexOf("</", end, StringComparison.Ordinal);
|
|
|
|
|
if (endTagStart < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var tag = line.Substring(i + 1, end - i - 1);
|
|
|
|
|
var text = line.Substring(end + 1, endTagStart - end - 1);
|
|
|
|
|
foreach (var ch in text)
|
|
|
|
|
{
|
2019-11-22 19:48:23 +01:00
|
|
|
|
var furiganaChar = BoutenTagToUnicode(tag);
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(furiganaChar))
|
|
|
|
|
{
|
|
|
|
|
var preFurigana = string.Empty;
|
|
|
|
|
if (actual.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
preFurigana = $"{{\\alpha&FF&}}{actual}{{\\alpha&0&}}";
|
|
|
|
|
}
|
|
|
|
|
furiganaList.Add(new Paragraph($"{preFurigana}{furiganaChar}", p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
actual.Append(ch);
|
|
|
|
|
actual.AppendLine();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var endTagEnd = line.IndexOf('>', endTagStart);
|
|
|
|
|
if (endTagEnd < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = endTagEnd + 1;
|
|
|
|
|
}
|
2019-11-22 19:48:23 +01:00
|
|
|
|
else if (line.Substring(i).StartsWith("<ruby-container>", StringComparison.Ordinal))
|
|
|
|
|
{
|
|
|
|
|
var baseTextStart = line.IndexOf("<ruby-base>", i, StringComparison.Ordinal);
|
|
|
|
|
var baseTextEnd = line.IndexOf("</ruby-base>", i, StringComparison.Ordinal);
|
|
|
|
|
if (baseTextStart < 0 || baseTextEnd < 0)
|
|
|
|
|
{
|
2019-11-23 06:31:18 +01:00
|
|
|
|
baseTextStart = line.IndexOf("<ruby-base-italic>", i, StringComparison.Ordinal);
|
|
|
|
|
baseTextEnd = line.IndexOf("</ruby-base-italic>", i, StringComparison.Ordinal);
|
|
|
|
|
if (baseTextStart < 0 || baseTextEnd < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-11-22 19:48:23 +01:00
|
|
|
|
}
|
|
|
|
|
baseTextStart += "<ruby-base>".Length;
|
|
|
|
|
var baseText = line.Substring(baseTextStart, baseTextEnd - baseTextStart);
|
|
|
|
|
|
|
|
|
|
var extraText = string.Empty;
|
|
|
|
|
var extraTextStart = line.IndexOf("<ruby-text>", i, StringComparison.Ordinal);
|
|
|
|
|
var extraTextEnd = line.IndexOf("</ruby-text>", i, StringComparison.Ordinal);
|
|
|
|
|
if (extraTextStart >= 0 || extraTextEnd >= 0 && extraTextStart < extraTextEnd)
|
|
|
|
|
{
|
|
|
|
|
extraTextStart += "<ruby-text>".Length;
|
|
|
|
|
extraText = line.Substring(extraTextStart, extraTextEnd - extraTextStart);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-23 06:31:18 +01:00
|
|
|
|
if (string.IsNullOrEmpty(extraText))
|
|
|
|
|
{
|
|
|
|
|
extraTextStart = line.IndexOf("<ruby-text-italic>", i, StringComparison.Ordinal);
|
|
|
|
|
extraTextEnd = line.IndexOf("</ruby-text-italic>", i, StringComparison.Ordinal);
|
|
|
|
|
if (extraTextStart >= 0 || extraTextEnd >= 0 && extraTextStart < extraTextEnd)
|
|
|
|
|
{
|
|
|
|
|
extraTextStart += "<ruby-text-italic>".Length;
|
|
|
|
|
extraText = line.Substring(extraTextStart, extraTextEnd - extraTextStart);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 19:48:23 +01:00
|
|
|
|
var extraTextAfter = string.Empty;
|
|
|
|
|
var extraTextStartAfter = line.IndexOf("<ruby-text-after>", i, StringComparison.Ordinal);
|
|
|
|
|
var extraTextEndAfter = line.IndexOf("</ruby-text-after>", i, StringComparison.Ordinal);
|
|
|
|
|
if (extraTextStartAfter >= 0 || extraTextEndAfter >= 0 && extraTextStartAfter < extraTextEndAfter)
|
|
|
|
|
{
|
|
|
|
|
extraTextStartAfter += "<ruby-text-after>".Length;
|
|
|
|
|
extraText = line.Substring(extraTextStartAfter, extraTextEndAfter - extraTextStartAfter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var preFurigana = string.Empty;
|
|
|
|
|
if (actual.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
preFurigana = $"{{\\alpha&FF&}}{actual.ToString().TrimEnd()}{{\\alpha&0&}}";
|
|
|
|
|
}
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(extraText))
|
|
|
|
|
{
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
foreach (var ch in extraText)
|
|
|
|
|
{
|
|
|
|
|
sb.Append(ch);
|
|
|
|
|
sb.AppendLine();
|
|
|
|
|
}
|
|
|
|
|
furiganaList.Add(new Paragraph($"{preFurigana}{{\\fs20}}{sb.ToString().TrimEnd()}", p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(extraTextAfter))
|
|
|
|
|
{
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
foreach (var ch in extraTextAfter)
|
|
|
|
|
{
|
|
|
|
|
sb.Append(ch);
|
|
|
|
|
sb.AppendLine();
|
|
|
|
|
}
|
|
|
|
|
furiganaList.Add(new Paragraph($"{preFurigana}{{\\fs20}} {sb.ToString().TrimEnd()}", p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var ch in baseText)
|
|
|
|
|
{
|
|
|
|
|
actual.Append(ch);
|
|
|
|
|
actual.AppendLine();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var endTagEnd = line.IndexOf("</ruby-container>", i, StringComparison.Ordinal);
|
|
|
|
|
if (endTagEnd < 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
i = endTagEnd + "</ruby-container>".Length;
|
|
|
|
|
rubyOn = true;
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
actual.AppendLine(line.Substring(i, 1));
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool displayBefore = lines.Count == 2 && index == 0 || lines.Count == 1;
|
2019-11-22 19:48:23 +01:00
|
|
|
|
if (displayBefore && furiganaList.Count > 0)
|
2019-11-22 08:46:25 +01:00
|
|
|
|
{
|
2019-11-22 19:48:23 +01:00
|
|
|
|
foreach (var fp in furiganaList)
|
|
|
|
|
{
|
|
|
|
|
var text = pre + "\\pos(" + startX + ",45)}" + fp.Text.TrimEnd();
|
|
|
|
|
list.Add(new Paragraph(text, p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
startX -= adjustment;
|
2019-11-22 19:48:23 +01:00
|
|
|
|
if (rubyOn && index == 0 && lines.Count == 2)
|
|
|
|
|
{
|
|
|
|
|
if (leftAlign)
|
|
|
|
|
{
|
|
|
|
|
startX -= 8;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
startX += 16;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var actualText = actual.ToString().TrimEnd();
|
|
|
|
|
actualText = pre + "\\pos(" + startX + ",40)}" + actualText;
|
|
|
|
|
|
|
|
|
|
// change horizontal chars to vertical version
|
|
|
|
|
actualText = actualText
|
|
|
|
|
.Replace('…', '⋮')
|
|
|
|
|
.Replace('〈', '︿')
|
|
|
|
|
.Replace('〉', '﹀')
|
|
|
|
|
.Replace('—', '︱') // em dash
|
2019-11-23 20:37:02 +01:00
|
|
|
|
.Replace('⸺', '︱') // double em dash (could not find double em dash vertical)
|
2019-11-23 06:31:18 +01:00
|
|
|
|
.Replace('ー', '⏐') // prolonged sound mark
|
2019-11-22 08:46:25 +01:00
|
|
|
|
.Replace('(', '︵')
|
2019-11-22 19:48:23 +01:00
|
|
|
|
.Replace(')', '︶');
|
2019-11-22 08:46:25 +01:00
|
|
|
|
|
|
|
|
|
list.Add(new Paragraph(actualText, p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
startX -= adjustment;
|
|
|
|
|
|
2019-11-22 19:48:23 +01:00
|
|
|
|
if (!displayBefore && furiganaList.Count > 0)
|
2019-11-22 08:46:25 +01:00
|
|
|
|
{
|
2019-11-22 19:48:23 +01:00
|
|
|
|
if (rubyOn && index == 1 && lines.Count == 2)
|
|
|
|
|
{
|
|
|
|
|
if (leftAlign)
|
|
|
|
|
{
|
|
|
|
|
startX += 14;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
startX -= 8;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
foreach (var fp in furiganaList)
|
|
|
|
|
{
|
|
|
|
|
var text = pre + "\\pos(" + startX + ",45)}" + fp.Text.TrimEnd();
|
|
|
|
|
list.Add(new Paragraph(text, p.StartTime.TotalMilliseconds, p.EndTime.TotalMilliseconds));
|
|
|
|
|
}
|
2019-11-22 08:46:25 +01:00
|
|
|
|
startX -= adjustment;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string Convert(Subtitle subtitle, int width, int height)
|
|
|
|
|
{
|
|
|
|
|
var finalSub = new Subtitle();
|
|
|
|
|
foreach (var paragraph in subtitle.Paragraphs)
|
|
|
|
|
{
|
|
|
|
|
finalSub.Paragraphs.AddRange(SplitToAssRenderLines(paragraph, width, height));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var oldFontSize = Configuration.Settings.SubtitleSettings.SsaFontSize;
|
|
|
|
|
var oldFontBold = Configuration.Settings.SubtitleSettings.SsaFontBold;
|
|
|
|
|
Configuration.Settings.SubtitleSettings.SsaFontSize = 40; // font size
|
|
|
|
|
Configuration.Settings.SubtitleSettings.SsaFontBold = false;
|
|
|
|
|
finalSub.Header = AdvancedSubStationAlpha.DefaultHeader;
|
|
|
|
|
Configuration.Settings.SubtitleSettings.SsaFontSize = oldFontSize;
|
|
|
|
|
Configuration.Settings.SubtitleSettings.SsaFontBold = oldFontBold;
|
|
|
|
|
|
|
|
|
|
finalSub.Header = finalSub.Header.Replace("PlayDepth: 0", @"PlayDepth: 0
|
|
|
|
|
PlayResX: 1280
|
|
|
|
|
PlayResY: 720").Replace("1280", width.ToString(CultureInfo.InvariantCulture))
|
|
|
|
|
.Replace("720", height.ToString(CultureInfo.InvariantCulture));
|
|
|
|
|
|
|
|
|
|
return finalSub.ToText(new AdvancedSubStationAlpha());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|