private static string CutLineLeftToWidth(string line, double width) { string last3 = line; while (Smi.GetLineWidth(line) > width) { last3 = line; line = line.Substring(1); } string last1 = line; while (Smi.GetLineWidth(line) < width) { last1 = line; line = " " + line; } if (width - Smi.GetLineWidth(last1) < Smi.GetLineWidth(line) - width) { line = last1; if (Smi.GetLineWidth(last3) - width < width - Smi.GetLineWidth(line)) { line = last3; } } return(line); }
// Cut 함수는 SubtitleObject.dll로 빼는 게 나을 듯? private static string CutLineRightToWidth(string line, double width) { string last3 = line; float t = 0; while ((t = Smi.GetLineWidth(line)) > width) { last3 = line; line = line.Substring(0, line.Length - 1); } string last1 = line; while (Smi.GetLineWidth(line) < width) { last1 = line; line += " "; } if (width - Smi.GetLineWidth(last1) < Smi.GetLineWidth(line) - width) { line = last1; if (Smi.GetLineWidth(last3) - width < width - Smi.GetLineWidth(line)) { line = last3; } } return(line); }
public static List <Smi> Combine(List <Smi> inputUpper, List <Smi> inputLower) { List <CombinedGroup> groups = new List <CombinedGroup>(); CombinedGroup lastGroup = new CombinedGroup(); Combined last = new Combined(); int ui = 0, li = 0; while (ui < inputUpper.Count && li < inputLower.Count) { Smi uLine = inputUpper[ui]; Smi lLine = inputLower[li]; int comp = uLine.start - lLine.start; if (comp < 0) { // 위 바뀜 if (last.lower.Length == 0) { // 아래가 빈 싱크인 상태로 위가 바뀜 -> 새 그룹 groups.Add((lastGroup = new CombinedGroup())); } lastGroup.combineds.Add((last = new Combined() { start = uLine.start, syncType = uLine.syncType, upper = uLine.text.Replace(" ", "").Length == 0 ? new string[] { } : Combined.ToLines(uLine.text), lower = (string[])last.lower.Clone() })); if (last.upper.Length > lastGroup.upperLineCount) { lastGroup.upperLineCount = last.upper.Length; } ui++; } else if (comp > 0) { // 아래 바뀜 if (last.upper.Length == 0) { // 위가 빈 싱크인 상태로 위가 바뀜 -> 새 그룹 groups.Add((lastGroup = new CombinedGroup())); } lastGroup.combineds.Add((last = new Combined() { start = lLine.start, syncType = lLine.syncType, upper = (string[])last.upper.Clone(), lower = lLine.text.Replace(" ", "").Length == 0 ? new string[] { } : Combined.ToLines(lLine.text) })); if (last.lower.Length > lastGroup.lowerLineCount) { lastGroup.lowerLineCount = last.lower.Length; } li++; } else { // 동시 // 새 그룹 groups.Add((lastGroup = new CombinedGroup())); lastGroup.combineds.Add((last = new Combined() { start = uLine.start, syncType = (uLine.syncType == SyncType.frame || lLine.syncType == SyncType.frame) ? SyncType.frame : SyncType.normal, upper = uLine.text.Replace(" ", "").Length == 0 ? new string[] { } : Combined.ToLines(uLine.text), lower = lLine.text.Replace(" ", "").Length == 0 ? new string[] { } : Combined.ToLines(lLine.text) })); lastGroup.upperLineCount = last.upper.Length; lastGroup.lowerLineCount = last.lower.Length; ui++; li++; } } for (; ui < inputUpper.Count; ui++) { Smi uLine = inputUpper[ui]; if (last.lower.Length == 0) { // 아래가 빈 싱크인 상태로 위가 바뀜 -> 새 그룹 groups.Add((lastGroup = new CombinedGroup())); } lastGroup.combineds.Add((last = new Combined() { start = uLine.start, syncType = uLine.syncType, upper = uLine.text.Replace(" ", "").Length == 0 ? new string[] { } : Combined.ToLines(uLine.text), lower = (string[])last.lower.Clone() })); if (last.upper.Length > lastGroup.upperLineCount) { lastGroup.upperLineCount = last.upper.Length; } } for (; li < inputLower.Count; li++) { Smi lLine = inputLower[li]; if (last.upper.Length == 0) { // 위가 빈 싱크인 상태로 위가 바뀜 -> 새 그룹 groups.Add((lastGroup = new CombinedGroup())); } lastGroup.combineds.Add((last = new Combined() { start = lLine.start, syncType = lLine.syncType, upper = (string[])last.upper.Clone(), lower = lLine.text.Replace(" ", "").Length == 0 ? new string[] { } : Combined.ToLines(lLine.text) })); if (last.lower.Length > lastGroup.lowerLineCount) { lastGroup.lowerLineCount = last.lower.Length; } } List <Smi> result = new List <Smi>(); foreach (CombinedGroup group in groups) { foreach (Combined combined in group.combineds) { int maxUpperIndex = 0, maxLowerIndex = 0; float maxUpperWidth = 0, maxLowerWidth = 0; for (int i = 0; i < combined.upper.Length; i++) { float width = Smi.GetLineWidth(combined.upper[i]); if (width > maxUpperWidth) { maxUpperIndex = i; maxUpperWidth = width; } } for (int i = 0; i < combined.lower.Length; i++) { float width = Smi.GetLineWidth(combined.lower[i]); if (width > maxLowerWidth) { maxLowerIndex = i; maxLowerWidth = width; } } // 정렬용 글자 수 맞춰주기 if (combined.upper.Length > 0 && combined.lower.Length > 0) { if (maxUpperWidth > maxLowerWidth) { //string left = Smi.GetLineAppend(combined.lower[maxLowerIndex], maxUpperWidth, true); string left = Width.GetAppend(Smi.GetLineWidth(combined.lower[maxLowerIndex]), maxUpperWidth, true); if (left.Length > 0) { string right = Width.AppendToRight(left); for (int i = 0; i < combined.lower.Length; i++) { //combined.lower[i] = "<b></b>" + left + combined.lower[i] + right + "<b></b>"; combined.lower[i] = left + combined.lower[i] + right; } } } else { //string left = Smi.GetLineAppend(combined.upper[maxUpperIndex], maxLowerWidth, true); string left = Width.GetAppend(Smi.GetLineWidth(combined.upper[maxUpperIndex]), maxLowerWidth, true); if (left.Length > 0) { string right = Width.AppendToRight(left); for (int i = 0; i < combined.upper.Length; i++) { //combined.upper[i] = "<b></b>" + left + combined.upper[i] + right + "<b></b>"; combined.upper[i] = left + combined.upper[i] + right; } } } } Smi smi = new Smi() { start = combined.start, syncType = combined.syncType, text = "" }; for (int i = 0; i < group.upperLineCount - combined.upper.Length; i++) { smi.text += "<b> </b>" + (i < group.upperLineCount - 1 ? "<br>" : ""); } for (int i = 0; i < combined.upper.Length; i++) { smi.text += combined.upper[i] + (i < combined.upper.Length - 1 ? "<br>" : ""); } if (group.upperLineCount > 0 && group.lowerLineCount > 0) { smi.text += "<br>"; } for (int i = 0; i < group.lowerLineCount - combined.lower.Length; i++) { smi.text += "<b> </b>" + (i < (group.lowerLineCount - 1) ? "<br>" : ""); } for (int i = 0; i < combined.lower.Length; i++) { smi.text += combined.lower[i] + (i < (combined.lower.Length - 1) ? "<br>" : ""); } if (smi.text.Length == 0) { smi.text = " "; } else { if (smi.text.StartsWith(" ") || smi.text.StartsWith(" ")) { smi.text = "" + smi.text; } if (smi.text.EndsWith(" ") || smi.text.EndsWith(" ")) { smi.text = smi.text + ""; } } result.Add(smi); } } return(result); }
public static List <Smi> Nico(List <NicoLine> nicoLines, int width) { int lineCount = 0; int startOfAll = int.MaxValue; int endOfAll = 0; foreach (NicoLine line in nicoLines) { if (line.line > lineCount) { lineCount = line.line; } if (line.start < startOfAll) { startOfAll = line.start; } if (line.end > endOfAll) { endOfAll = line.end; } } int startFrame = (int)Math.Round(startOfAll / FRAME_LENGTH); int endFrame = (int)Math.Round(endOfAll / FRAME_LENGTH); List <List <NicoLine> > lines = new List <List <NicoLine> >(); for (int i = 0; i < lineCount; i++) { lines.Add(new List <NicoLine>()); } foreach (NicoLine line in nicoLines) { lines[line.line - 1].Add(line); } string defaultValue = ""; for (int i = 0; i < width; i++) { defaultValue += " "; } NicoLine.lineWidth = Smi.GetLineWidth(defaultValue); List <Smi> output = new List <Smi>(); for (int frame = startFrame; frame < endFrame; frame++) { Smi smi = new Smi() { start = (int)(frame * FRAME_LENGTH), syncType = (frame == startFrame ? SyncType.frame : SyncType.inner), text = "" }; for (int i = 0; i < lineCount; i++) { string result = defaultValue; foreach (NicoLine line in lines[i]) { float pos = line.CalcLeft(frame); if (pos < 0) { // 왼쪽이 잘리기 시작 float leftWidth = pos + line.width; if (leftWidth > 0) { // 화면에 남는 부분이 있음 if (leftWidth >= NicoLine.lineWidth) { // 남는 부분이 화면보다 큼 result = CutLineLeftToWidth(line.text, leftWidth); result = CutLineRightToWidth(line.text, NicoLine.lineWidth); } else { // 남는 부분이 화면보다 작음 string text = CutLineLeftToWidth(line.text, leftWidth); result = text + CutLineLeftToWidth(result, NicoLine.lineWidth - leftWidth); } } } else if (pos < NicoLine.lineWidth) { // 화면 안에서 시작 string lastResult = result; result = CutLineRightToWidth(result, pos) + line.text; float thisWidth = Smi.GetLineWidth(result); if (thisWidth > NicoLine.lineWidth) { result = CutLineRightToWidth(result, NicoLine.lineWidth); } else { result += CutLineLeftToWidth(lastResult, NicoLine.lineWidth - thisWidth); } } } smi.text += (i == 0 ? "" : "<br>") + result; } smi.text += ""; output.Add(smi); } output.Add(new Smi() { start = (int)(endFrame * FRAME_LENGTH), syncType = SyncType.frame, text = " " }); return(output); }