/// <summary> /// Even after taking months to fix a regression that completely broke the use of multiple formats /// in one subtitle, YouTube still hasn't got the Javascript code down. While changing the background /// color in the middle of a line now works again, changing it before or after a line break results /// in the rounded corners disappearing on one side. It doesn't look pretty. /// The only workaround seems to be to split the subtitle in two. /// </summary> private void SplitMultiBackgroundLine(int lineIndex) { Line line = Lines[lineIndex]; int numLineBreaks = line.Sections.SelectMany(s => s.Text).Count(c => c == '\n'); if (numLineBreaks != 1) { return; } int secondSubLineStartSectionIdx = -1; for (int i = 1; i < line.Sections.Count; i++) { Section prevSection = line.Sections[i - 1]; Section section = line.Sections[i]; if ((prevSection.BackColor != section.BackColor || prevSection.Font != section.Font || prevSection.Scale != section.Scale) && (prevSection.Text.EndsWith("\r\n") || section.Text.StartsWith("\r\n"))) { secondSubLineStartSectionIdx = i; break; } } if (secondSubLineStartSectionIdx < 0) { return; } Line secondLine = (Line)line.Clone(); line.Sections.RemoveRange(secondSubLineStartSectionIdx, line.Sections.Count - secondSubLineStartSectionIdx); line.Sections[secondSubLineStartSectionIdx - 1].Text = line.Sections[secondSubLineStartSectionIdx - 1].Text.Replace("\r\n", ""); secondLine.Sections.RemoveRange(0, secondSubLineStartSectionIdx); secondLine.Sections[0].Text = secondLine.Sections[0].Text.Replace("\r\n", ""); PointF position = line.Position ?? GetDefaultPosition(line.AnchorPoint); if (AnchorPointUtil.IsTopAligned(line.AnchorPoint)) { position.Y += VideoDimensions.Height * 0.05f; line.AnchorPoint = AnchorPointUtil.GetVerticalOpposite(line.AnchorPoint); } else if (AnchorPointUtil.IsMiddleAligned(line.AnchorPoint)) { line.AnchorPoint = AnchorPointUtil.MakeBottomAligned(line.AnchorPoint); secondLine.AnchorPoint = AnchorPointUtil.MakeTopAligned(secondLine.AnchorPoint); } else { position.Y -= VideoDimensions.Height * 0.05f; secondLine.AnchorPoint = AnchorPointUtil.GetVerticalOpposite(secondLine.AnchorPoint); } line.Position = position; secondLine.Position = position; Lines.Insert(lineIndex + 1, secondLine); }
private static string GetVerticalAlign(AssStyle style, AssStyleOptions options) { if (!(options?.HasExistingBackgroundImage ?? false)) { return("middle"); } if (AnchorPointUtil.IsTopAligned(style.AnchorPoint)) { return("top"); } if (AnchorPointUtil.IsBottomAligned(style.AnchorPoint)) { return("bottom"); } return("middle"); }
private static string GetTextAlign(AssStyle style, AssStyleOptions options) { if (!(options?.HasExistingBackgroundImage ?? false)) { return("center"); } if (AnchorPointUtil.IsLeftAligned(style.AnchorPoint)) { return("left"); } if (AnchorPointUtil.IsRightAligned(style.AnchorPoint)) { return("right"); } return("center"); }
public void MergeSimultaneousLines() { List <Line> lines = Lines.Where(l => l.Start < l.End) .OrderBy(l => l.Start).ToList(); // Use OrderBy to get a stable sort (List.Sort() is unstable) int i = 0; while (i < lines.Count) { if (lines[i].Position != null) { i++; continue; } Line firstLine = lines[i]; Line secondLine = null; int j = i + 1; while (j < lines.Count && lines[j].Start < lines[i].End) { if (lines[j].Position == null && lines[j].AnchorPoint == firstLine.AnchorPoint) { secondLine = lines[j]; break; } j++; } if (secondLine == null) { i++; continue; } lines.RemoveAt(j); lines.RemoveAt(i); if (firstLine.Start < secondLine.Start) { InsertConcatenedLine(lines, i, firstLine.Start, secondLine.Start, false, firstLine); } if (AnchorPointUtil.IsBottomAligned(firstLine.AnchorPoint)) { InsertConcatenedLine(lines, i, secondLine.Start, TimeUtil.Min(firstLine.End, secondLine.End), false, secondLine, firstLine); } else { InsertConcatenedLine(lines, i, secondLine.Start, TimeUtil.Min(firstLine.End, secondLine.End), false, firstLine, secondLine); } if (firstLine.End < secondLine.End) { InsertConcatenedLine(lines, i, firstLine.End, secondLine.End, true, secondLine); } else if (secondLine.End < firstLine.End) { InsertConcatenedLine(lines, i, secondLine.End, firstLine.End, false, firstLine); } } Lines.Clear(); Lines.AddRange(lines); }