/// @brief Converts whole file to TTXT /// void TTXTSubtitleFormat::ConvertToTTXT () { // Convert SortLines(); StripComments(); RecombineOverlaps(); MergeIdentical(); ConvertTags(1,_T("\r\n")); // Find last line AssTime lastTime; for (std::list<AssEntry*>::reverse_iterator cur=Line->rbegin();cur!=Line->rend();cur++) { AssDialogue *prev = dynamic_cast<AssDialogue*>(*cur); if (prev) { lastTime = prev->End; break; } } // Insert blank line at the end AssDialogue *diag = new AssDialogue(); diag->Start.SetMS(lastTime.GetMS()); diag->End.SetMS(lastTime.GetMS()+OPT_GET("Timing/Default Duration")->GetInt()); diag->group = _T("[Events]"); diag->Style = _T("Default"); diag->Comment = false; Line->push_back(diag); }
/// @brief Process a dialogue line /// @param node /// @return /// bool TTXTSubtitleFormat::ProcessLine(wxXmlNode *node) { // Get time wxString sampleTime = node->GetAttribute(_T("sampleTime"),_T("00:00:00.000")); AssTime time; time.ParseASS(sampleTime); // Set end time of last line if (diag) diag->End = time; diag = NULL; // Get text wxString text; if (version == 0) text = node->GetAttribute(_T("text"),_T("")); else text = node->GetNodeContent(); // Create line if (!text.IsEmpty()) { // Create dialogue diag = new AssDialogue(); diag->Start.SetMS(time.GetMS()); diag->End.SetMS(36000000-10); diag->group = _T("[Events]"); diag->Style = _T("Default"); diag->Comment = false; // Process text for 1.0 if (version == 0) { wxString finalText; finalText.Alloc(text.Length()); bool in = false; bool first = true; for (size_t i=0;i<text.Length();i++) { if (text[i] == _T('\'')) { if (!in && !first) finalText += _T("\\N"); first = false; in = !in; } else if (in) finalText += text[i]; } diag->Text = finalText; } // Process text for 1.1 else { text.Replace(_T("\r"),_T("")); text.Replace(_T("\n"),_T("\\N")); diag->Text = text; } // Insert dialogue Line->push_back(diag); return true; } else return false; }
static void read_subtitles(agi::ProgressSink *ps, MatroskaFile *file, MkvStdIO *input, bool srt, double totalTime, AssParser *parser) { std::vector<std::pair<int, std::string>> subList; // Load blocks ulonglong startTime, endTime, filePos; unsigned int rt, frameSize, frameFlags; while (mkv_ReadFrame(file, 0, &rt, &startTime, &endTime, &filePos, &frameSize, &frameFlags) == 0) { if (ps->IsCancelled()) return; if (frameSize == 0) continue; const auto readBuf = input->file.read(filePos, frameSize); const auto readBufEnd = readBuf + frameSize; // Get start and end times longlong timecodeScaleLow = 1000000; AssTime subStart = startTime / timecodeScaleLow; AssTime subEnd = endTime / timecodeScaleLow; using str_range = boost::iterator_range<const char *>; // Process SSA/ASS if (!srt) { auto first = std::find(readBuf, readBufEnd, ','); if (first == readBufEnd) continue; auto second = std::find(first + 1, readBufEnd, ','); if (second == readBufEnd) continue; subList.emplace_back( boost::lexical_cast<int>(str_range(readBuf, first)), str(boost::format("Dialogue: %d,%s,%s,%s") % boost::lexical_cast<int>(str_range(first + 1, second)) % subStart.GetAssFormated() % subEnd.GetAssFormated() % str_range(second + 1, readBufEnd))); } // Process SRT else { auto line = str(boost::format("Dialogue: 0,%s,%s,Default,,0,0,0,,%s") % subStart.GetAssFormated() % subEnd.GetAssFormated() % str_range(readBuf, readBufEnd)); boost::replace_all(line, "\r\n", "\\N"); boost::replace_all(line, "\r", "\\N"); boost::replace_all(line, "\n", "\\N"); subList.emplace_back(subList.size(), std::move(line)); } ps->SetProgress(startTime / timecodeScaleLow, totalTime); } // Insert into file sort(begin(subList), end(subList)); for (auto order_value_pair : subList) parser->AddLine(order_value_pair.second); }
bool operator != (AssTime &t1, AssTime &t2) { return (t1.GetMS() != t2.GetMS()); }
bool operator > (AssTime &t1, AssTime &t2) { return (t1.GetMS() > t2.GetMS()); }
////////////////////// // AssTime comparison bool operator < (AssTime &t1, AssTime &t2) { return (t1.GetMS() < t2.GetMS()); }
///////////////////// // Set column widths void BaseGrid::SetColumnWidths() { // Width/height int w = 0; int h = 0; GetClientSize(&w,&h); // DC for text extents test wxClientDC dc(this); dc.SetFont(font); int fw,fh; //dc.GetTextExtent(_T("#TWFfgGhH"), &fw, &fh, NULL, NULL, &font); // O(1) widths dc.GetTextExtent(_T("0000"), &fw, &fh, NULL, NULL, &font); int marginLen = fw + 10; dc.GetTextExtent(wxString::Format(_T("%i"),GetRows()), &fw, &fh, NULL, NULL, &font); int labelLen = fw + 10; int startLen = 0; int endLen = 0; if (!byFrame) { AssTime time; dc.GetTextExtent(time.GetASSFormated(), &fw, &fh, NULL, NULL, &font); startLen = fw + 10; endLen = fw + 10; } // O(n) widths int actorLen = 0; int effectLen = 0; int maxLayer = 0; int maxStart = 0; int maxEnd = 0; AssDialogue *curDiag; for (int i=0;i<GetRows();i++) { curDiag = GetDialogue(i); if (curDiag) { // Layer if (curDiag->Layer > maxLayer) maxLayer = curDiag->Layer; // Actor if (!curDiag->Actor.IsEmpty()) { dc.GetTextExtent(curDiag->Actor, &fw, &fh, NULL, NULL, &font); if (fw > actorLen) actorLen = fw; } // Effect if (!curDiag->Effect.IsEmpty()) { dc.GetTextExtent(curDiag->Effect, &fw, &fh, NULL, NULL, &font); if (fw > effectLen) effectLen = fw; } // Times if (byFrame) { int tmp = VFR_Output.GetFrameAtTime(curDiag->Start.GetMS(),true); if (tmp > maxStart) maxStart = tmp; tmp = VFR_Output.GetFrameAtTime(curDiag->End.GetMS(),true); if (tmp > maxEnd) maxEnd = tmp; } } } // Finish layer dc.GetTextExtent(wxString::Format(_T("%i"),maxLayer), &fw, &fh, NULL, NULL, &font); int layerLen = fw + 10; // Finish times if (byFrame) { dc.GetTextExtent(wxString::Format(_T("%i"),maxStart), &fw, &fh, NULL, NULL, &font); startLen = fw + 10; dc.GetTextExtent(wxString::Format(_T("%i"),maxEnd), &fw, &fh, NULL, NULL, &font); endLen = fw + 10; } // Finish actor/effect if (actorLen) actorLen += 10; if (effectLen) effectLen += 10; // Style length int styleLen = 0; AssStyle *curStyle; if (AssFile::top) { for (entryIter curIter=AssFile::top->Line.begin();curIter!=AssFile::top->Line.end();curIter++) { curStyle = AssEntry::GetAsStyle(*curIter); if (curStyle) { dc.GetTextExtent(curStyle->name, &fw, &fh, NULL, NULL, &font); if (fw > styleLen) styleLen = fw; } } } styleLen += 10; // Set column widths colWidth[0] = labelLen; colWidth[1] = layerLen; colWidth[2] = startLen; colWidth[3] = endLen; colWidth[4] = styleLen; colWidth[5] = actorLen; colWidth[6] = effectLen; colWidth[7] = marginLen; colWidth[8] = marginLen; colWidth[9] = marginLen; // Set size of last int total = 0; for (int i=0;i<10;i++) total+= colWidth[i]; colWidth[10] = w-total; }