Fix issues with RecombineOverlaps

This commit is contained in:
Thomas Goyne 2014-03-24 11:43:06 -07:00
parent e71270f0f0
commit 5214efd553

View file

@ -197,33 +197,26 @@ void SubtitleFormat::StripComments(AssFile &file) {
}, [](AssDialogue *e) { delete e; }); }, [](AssDialogue *e) { delete e; });
} }
static bool dialog_start_lt(AssDialogue &pos, AssDialogue *to_insert) {
return pos.Start > to_insert->Start;
}
/// @brief Split and merge lines so there are no overlapping lines /// @brief Split and merge lines so there are no overlapping lines
/// ///
/// Algorithm described at http://devel.aegisub.org/wiki/Technical/SplitMerge /// Algorithm described at http://devel.aegisub.org/wiki/Technical/SplitMerge
void SubtitleFormat::RecombineOverlaps(AssFile &file) { void SubtitleFormat::RecombineOverlaps(AssFile &file) {
auto next = file.Events.begin(); auto cur = file.Events.begin();
auto cur = next++; for (auto next = std::next(cur); next != file.Events.end(); cur = std::prev(next)) {
if (next == file.Events.begin() || cur->End <= next->Start) {
++next;
continue;
}
for (; next != file.Events.end(); cur = next++) { std::unique_ptr<AssDialogue> prevdlg(&*cur);
AssDialogue *prevdlg = &*cur; std::unique_ptr<AssDialogue> curdlg(&*next);
AssDialogue *curdlg = &*next; ++next;
if (prevdlg->End <= curdlg->Start) continue;
// Use names like in the algorithm description and prepare for erasing auto insert_line = [&](AssDialogue *newdlg) {
// old dialogues from the list file.Events.insert(std::find_if(next, file.Events.end(), [&](AssDialogue const& pos) {
auto prev = cur; return pos.Start >= newdlg->Start;
cur = next; }), *newdlg);
next++; };
// std::list::insert() inserts items before the given iterator, so
// we need 'next' for inserting. 'prev' and 'cur' can safely be erased
// from the list now.
file.Events.erase(prev);
file.Events.erase(cur);
//Is there an A part before the overlap? //Is there an A part before the overlap?
if (curdlg->Start > prevdlg->Start) { if (curdlg->Start > prevdlg->Start) {
@ -232,8 +225,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) {
newdlg->Start = prevdlg->Start; newdlg->Start = prevdlg->Start;
newdlg->End = curdlg->Start; newdlg->End = curdlg->Start;
newdlg->Text = prevdlg->Text; newdlg->Text = prevdlg->Text;
insert_line(newdlg);
file.Events.insert(find_if(next, file.Events.end(), std::bind(dialog_start_lt, _1, newdlg)), *newdlg);
} }
// Overlapping A+B part // Overlapping A+B part
@ -243,8 +235,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) {
newdlg->End = (prevdlg->End < curdlg->End) ? prevdlg->End : curdlg->End; newdlg->End = (prevdlg->End < curdlg->End) ? prevdlg->End : curdlg->End;
// Put an ASS format hard linewrap between lines // Put an ASS format hard linewrap between lines
newdlg->Text = curdlg->Text.get() + "\\N" + prevdlg->Text.get(); newdlg->Text = curdlg->Text.get() + "\\N" + prevdlg->Text.get();
insert_line(newdlg);
file.Events.insert(find_if(next, file.Events.end(), std::bind(dialog_start_lt, _1, newdlg)), *newdlg);
} }
// Is there an A part after the overlap? // Is there an A part after the overlap?
@ -254,8 +245,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) {
newdlg->Start = curdlg->End; newdlg->Start = curdlg->End;
newdlg->End = prevdlg->End; newdlg->End = prevdlg->End;
newdlg->Text = prevdlg->Text; newdlg->Text = prevdlg->Text;
insert_line(newdlg);
file.Events.insert(find_if(next, file.Events.end(), std::bind(dialog_start_lt, _1, newdlg)), *newdlg);
} }
// Is there a B part after the overlap? // Is there a B part after the overlap?
@ -265,11 +255,8 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) {
newdlg->Start = prevdlg->End; newdlg->Start = prevdlg->End;
newdlg->End = curdlg->End; newdlg->End = curdlg->End;
newdlg->Text = curdlg->Text; newdlg->Text = curdlg->Text;
insert_line(newdlg);
file.Events.insert(find_if(next, file.Events.end(), std::bind(dialog_start_lt, _1, newdlg)), *newdlg);
} }
next--;
} }
} }